/*
 * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

use anyhow::Context;
use bzip2::write::BzEncoder;
use chrono::{Datelike, Local, TimeZone, Timelike};

use crc32fast::Hasher;
use flate2::write::DeflateEncoder;
use flate2::Compression;

use std::collections::HashSet;
use std::fs::{metadata, File};
use std::io::Seek;
use std::io::SeekFrom;
use std::io::{self, Read, Write};
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;

use crate::encryption::zipcrypt::{ZipCryptoDecryptor, ZipCryptoEncryptor};

use crate::utils::common::get_file_modification_time;

pub const ZIP_CRYPTO_FLAG: u16 = 0x1;
pub const VERSION_MADE: u16 = 0x031E; // 3.0 (Unix)
pub const VERSION_NEEDED: u16 = 0x0A; // 1.0
pub const VERSION_NEEDED_ZIP64: u16 = 0x2D; // 4.5 for ZIP64
#[allow(dead_code)]
pub const CENTRAL_DIR_HEADER_SIZE: usize = 46;
#[allow(dead_code)]
pub const END_OF_CENTRAL_DIR_SIZE: usize = 22;

// ZIP64常量
pub const ZIP64_VERSION_MADE: u16 = 0x032D; // 4.5 (Unix)
pub const ZIP64_EXTRA_FIELD_ID: u16 = 0x0001; // ZIP64扩展信息额外字段标识符
#[allow(dead_code)]
pub const ZIP64_END_OF_CENTRAL_DIR_SIZE: usize = 56; // ZIP64结束目录记录大小
pub const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE: usize = 20; // ZIP64结束目录定位器大小
pub const MAX_ZIP_SIZE: u32 = 0xFFFFFFFF; // 4GB - 1 (ZIP格式32位限制)
pub const MAX_ZIP_ENTRIES: u16 = 0xFFFF; // 65535 (ZIP格式16位限制)

// ZIP64扩展信息结构
#[derive(Debug, Clone, Default)]
pub struct Zip64ExtendedInfo {
    pub uncompressed_size: Option<u64>,
    pub compressed_size: Option<u64>,
    pub local_header_offset: Option<u64>,
    pub disk_start_number: Option<u32>,
}

impl Zip64ExtendedInfo {
    pub fn new() -> Self {
        Self::default()
    }

    // 根据ZIP64规范，extra field的字段顺序必须是固定的
    // 并且只有当标准字段为最大值时，对应的ZIP64字段才会被写入
    pub fn to_bytes(
        &self,
        uncompressed_max: bool,
        compressed_max: bool,
        offset_max: bool,
    ) -> Vec<u8> {
        let mut data = Vec::new();

        // 按照ZIP64规范的固定顺序写入字段
        if uncompressed_max {
            if let Some(size) = self.uncompressed_size {
                data.extend_from_slice(&size.to_le_bytes());
            }
        }
        if compressed_max {
            if let Some(size) = self.compressed_size {
                data.extend_from_slice(&size.to_le_bytes());
            }
        }
        if offset_max {
            if let Some(offset) = self.local_header_offset {
                data.extend_from_slice(&offset.to_le_bytes());
            }
        }
        // 磁盘编号字段（通常不用于单个文件）
        if let Some(disk) = self.disk_start_number {
            data.extend_from_slice(&disk.to_le_bytes());
        }

        data
    }

    // 向后兼容的方法
    #[allow(dead_code)]
    pub fn to_bytes_compat(&self) -> Vec<u8> {
        let mut data = Vec::new();

        if let Some(size) = self.uncompressed_size {
            data.extend_from_slice(&size.to_le_bytes());
        }
        if let Some(size) = self.compressed_size {
            data.extend_from_slice(&size.to_le_bytes());
        }
        if let Some(offset) = self.local_header_offset {
            data.extend_from_slice(&offset.to_le_bytes());
        }
        if let Some(disk) = self.disk_start_number {
            data.extend_from_slice(&disk.to_le_bytes());
        }

        data
    }

    pub fn from_bytes(data: &[u8]) -> anyhow::Result<Self> {
        let mut info = Self::new();
        let mut offset = 0;
        // 根据数据长度确定包含哪些字段
        if data.len() >= 8 {
            info.uncompressed_size = Some(u64::from_le_bytes(data[offset..offset + 8].try_into()?));
            offset += 8;
        }
        if data.len() >= 16 {
            info.compressed_size = Some(u64::from_le_bytes(data[offset..offset + 8].try_into()?));
            offset += 8;
        }
        if data.len() >= 24 {
            info.local_header_offset =
                Some(u64::from_le_bytes(data[offset..offset + 8].try_into()?));
            offset += 8;
        }
        if data.len() >= 28 {
            info.disk_start_number = Some(u32::from_le_bytes(data[offset..offset + 4].try_into()?));
        }

        Ok(info)
    }
}

// ZIP64结束目录记录
#[derive(Debug, Clone)]
pub struct Zip64EndOfCentralDir {
    pub size_of_record: u64,
    pub version_made: u16,
    pub version_needed: u16,
    pub disk_number: u32,
    pub central_dir_disk: u32,
    pub entries_on_disk: u64,
    pub total_entries: u64,
    pub central_dir_size: u64,
    pub central_dir_offset: u64,
}

impl Default for Zip64EndOfCentralDir {
    fn default() -> Self {
        Self {
            size_of_record: 44, // 固定大小（不包括可变长度扩展数据）
            version_made: ZIP64_VERSION_MADE,
            version_needed: VERSION_NEEDED_ZIP64,
            disk_number: 0,
            central_dir_disk: 0,
            entries_on_disk: 0,
            total_entries: 0,
            central_dir_size: 0,
            central_dir_offset: 0,
        }
    }
}

// ZIP64结束目录定位器
#[derive(Debug, Clone)]
pub struct Zip64EndOfCentralDirLocator {
    pub central_dir_disk: u32,
    pub zip64_end_offset: u64,
    pub total_disks: u32,
}

impl Default for Zip64EndOfCentralDirLocator {
    fn default() -> Self {
        Self {
            central_dir_disk: 0,
            zip64_end_offset: 0,
            total_disks: 1,
        }
    }
}

// 检测是否需要ZIP64格式的辅助函数
pub fn needs_zip64(
    uncompressed_size: u64,
    compressed_size: u64,
    local_header_offset: u64,
    total_entries: usize,
) -> bool {
    uncompressed_size > MAX_ZIP_SIZE as u64
        || compressed_size > MAX_ZIP_SIZE as u64
        || local_header_offset > MAX_ZIP_SIZE as u64
        || total_entries > MAX_ZIP_ENTRIES as usize
}

// 检测归档是否需要ZIP64格式
pub fn archive_needs_zip64(
    total_entries: usize,
    central_dir_size: u64,
    central_dir_offset: u64,
) -> bool {
    total_entries > MAX_ZIP_ENTRIES as usize
        || central_dir_size > MAX_ZIP_SIZE as u64
        || central_dir_offset > MAX_ZIP_SIZE as u64
}

// ZIP文件头结构
pub struct LocalFileHeader {
    pub version_needed: u16,
    pub flags: u16, // 需要设置加密标志位
    pub compression: CompressionMethod,
    pub mod_time: u16,
    pub mod_date: u16,
    pub crc32: u32,
    pub compressed_size: u32,
    pub uncompressed_size: u32,
    pub filename: Vec<u8>,
    pub extra_field: Vec<u8>,
    // ZIP64支持
    pub zip64_extended_info: Option<Zip64ExtendedInfo>,
}

impl LocalFileHeader {
    pub fn new() -> Self {
        Self {
            version_needed: VERSION_NEEDED,
            flags: 0,
            compression: CompressionMethod::Deflated,
            mod_time: 0,
            mod_date: 0,
            crc32: 0,
            compressed_size: 0,
            uncompressed_size: 0,
            filename: Vec::new(),
            extra_field: Vec::new(),
            zip64_extended_info: None,
        }
    }

    #[allow(dead_code)]
    pub fn needs_zip64(&self) -> bool {
        let uncompressed = self.get_uncompressed_size();
        let compressed = self.get_compressed_size();

        uncompressed > MAX_ZIP_SIZE as u64 || compressed > MAX_ZIP_SIZE as u64
    }

    #[allow(dead_code)]
    pub fn get_uncompressed_size(&self) -> u64 {
        self.zip64_extended_info
            .as_ref()
            .and_then(|info| info.uncompressed_size)
            .unwrap_or(self.uncompressed_size as u64)
    }

    #[allow(dead_code)]
    pub fn get_compressed_size(&self) -> u64 {
        self.zip64_extended_info
            .as_ref()
            .and_then(|info| info.compressed_size)
            .unwrap_or(self.compressed_size as u64)
    }

    pub fn set_zip64_info(&mut self, uncompressed_size: u64, compressed_size: u64) {
        if needs_zip64(uncompressed_size, compressed_size, 0, 0) {
            let mut zip64_info = Zip64ExtendedInfo::new();
            zip64_info.uncompressed_size = Some(uncompressed_size);
            zip64_info.compressed_size = Some(compressed_size);

            self.zip64_extended_info = Some(zip64_info);
            self.version_needed = VERSION_NEEDED_ZIP64;

            // 设置标准字段为最大值或实际值
            self.uncompressed_size = if uncompressed_size > MAX_ZIP_SIZE as u64 {
                MAX_ZIP_SIZE
            } else {
                uncompressed_size as u32
            };
            self.compressed_size = if compressed_size > MAX_ZIP_SIZE as u64 {
                MAX_ZIP_SIZE
            } else {
                compressed_size as u32
            };

            // 更新extra_field
            self.update_extra_field();
        } else {
            self.uncompressed_size = uncompressed_size as u32;
            self.compressed_size = compressed_size as u32;
        }
    }

    fn update_extra_field(&mut self) {
        if let Some(zip64_info) = self.zip64_extended_info.clone() {
            // 移除旧的ZIP64 extra field（如果存在）
            self.remove_zip64_extra_field();

            // 检查哪些字段需要ZIP64扩展
            let uncompressed_max = self.uncompressed_size == MAX_ZIP_SIZE;
            let compressed_max = self.compressed_size == MAX_ZIP_SIZE;

            // 添加新的ZIP64 extra field
            let zip64_data = zip64_info.to_bytes(uncompressed_max, compressed_max, false);
            if !zip64_data.is_empty() {
                let mut extra_field = Vec::new();
                extra_field.extend_from_slice(&ZIP64_EXTRA_FIELD_ID.to_le_bytes());
                extra_field.extend_from_slice(&(zip64_data.len() as u16).to_le_bytes());
                extra_field.extend_from_slice(&zip64_data);

                // 将ZIP64 extra field添加到现有extra field的开头
                extra_field.extend_from_slice(&self.extra_field);
                self.extra_field = extra_field;
            }
        }
    }

    fn remove_zip64_extra_field(&mut self) {
        let mut new_extra_field = Vec::new();
        let mut offset = 0;

        while offset + 4 <= self.extra_field.len() {
            let header_id =
                u16::from_le_bytes([self.extra_field[offset], self.extra_field[offset + 1]]);
            let data_size =
                u16::from_le_bytes([self.extra_field[offset + 2], self.extra_field[offset + 3]])
                    as usize;

            if header_id != ZIP64_EXTRA_FIELD_ID {
                // 保留非ZIP64的extra field
                let end = offset + 4 + data_size;
                if end <= self.extra_field.len() {
                    new_extra_field.extend_from_slice(&self.extra_field[offset..end]);
                }
            }

            offset += 4 + data_size;
        }

        self.extra_field = new_extra_field;
    }
}

impl Default for LocalFileHeader {
    fn default() -> Self {
        Self::new()
    }
}

// 中央目录结构
#[derive(Default, Debug, Clone)]
pub struct CentralDirectoryHeader {
    pub version_made: u16,
    pub version_needed: u16,
    pub flags: u16,
    pub compression: CompressionMethod,
    pub mod_time: u16,
    pub mod_date: u16,
    pub crc32: u32,
    pub compressed_size: u32,
    pub uncompressed_size: u32,
    pub filename: Vec<u8>,
    pub extra_field: Vec<u8>,
    pub file_comment: Vec<u8>,
    pub disk_num: u16,
    pub internal_attr: u16,
    pub external_attr: u32,
    pub local_header_offset: u32,
    // ZIP64支持
    pub zip64_extended_info: Option<Zip64ExtendedInfo>,
}
impl CentralDirectoryHeader {
    #[allow(dead_code)]
    pub fn new() -> Self {
        Self {
            version_made: VERSION_MADE,
            version_needed: VERSION_NEEDED,
            zip64_extended_info: None,
            ..Default::default()
        }
    }

    pub fn needs_zip64(&self) -> bool {
        let uncompressed = self.get_uncompressed_size();
        let compressed = self.get_compressed_size();
        let offset = self.get_local_header_offset();

        uncompressed > MAX_ZIP_SIZE as u64
            || compressed > MAX_ZIP_SIZE as u64
            || offset > MAX_ZIP_SIZE as u64
    }

    pub fn get_uncompressed_size(&self) -> u64 {
        self.zip64_extended_info
            .as_ref()
            .and_then(|info| info.uncompressed_size)
            .unwrap_or(self.uncompressed_size as u64)
    }

    pub fn get_compressed_size(&self) -> u64 {
        self.zip64_extended_info
            .as_ref()
            .and_then(|info| info.compressed_size)
            .unwrap_or(self.compressed_size as u64)
    }

    pub fn get_local_header_offset(&self) -> u64 {
        self.zip64_extended_info
            .as_ref()
            .and_then(|info| info.local_header_offset)
            .unwrap_or(self.local_header_offset as u64)
    }

    pub fn set_zip64_info(
        &mut self,
        uncompressed_size: u64,
        compressed_size: u64,
        local_header_offset: u64,
    ) {
        if needs_zip64(uncompressed_size, compressed_size, local_header_offset, 0) {
            let mut zip64_info = Zip64ExtendedInfo::new();
            zip64_info.uncompressed_size = Some(uncompressed_size);
            zip64_info.compressed_size = Some(compressed_size);
            zip64_info.local_header_offset = Some(local_header_offset);

            self.zip64_extended_info = Some(zip64_info);
            self.version_made = ZIP64_VERSION_MADE;
            self.version_needed = VERSION_NEEDED_ZIP64;

            // 设置标准字段为最大值或实际值
            self.uncompressed_size = if uncompressed_size > MAX_ZIP_SIZE as u64 {
                MAX_ZIP_SIZE
            } else {
                uncompressed_size as u32
            };
            self.compressed_size = if compressed_size > MAX_ZIP_SIZE as u64 {
                MAX_ZIP_SIZE
            } else {
                compressed_size as u32
            };
            self.local_header_offset = if local_header_offset > MAX_ZIP_SIZE as u64 {
                MAX_ZIP_SIZE
            } else {
                local_header_offset as u32
            };

            // 更新extra_field
            self.update_extra_field();
        } else {
            self.uncompressed_size = uncompressed_size as u32;
            self.compressed_size = compressed_size as u32;
            self.local_header_offset = local_header_offset as u32;
        }
    }

    fn update_extra_field(&mut self) {
        if let Some(zip64_info) = self.zip64_extended_info.clone() {
            // 移除旧的ZIP64 extra field（如果存在）
            self.remove_zip64_extra_field();

            // 检查哪些字段需要ZIP64扩展
            let uncompressed_max = self.uncompressed_size == MAX_ZIP_SIZE;
            let compressed_max = self.compressed_size == MAX_ZIP_SIZE;
            let offset_max = self.local_header_offset == MAX_ZIP_SIZE;

            // 添加新的ZIP64 extra field
            let zip64_data = zip64_info.to_bytes(uncompressed_max, compressed_max, offset_max);
            if !zip64_data.is_empty() {
                let mut extra_field = Vec::new();
                extra_field.extend_from_slice(&ZIP64_EXTRA_FIELD_ID.to_le_bytes());
                extra_field.extend_from_slice(&(zip64_data.len() as u16).to_le_bytes());
                extra_field.extend_from_slice(&zip64_data);

                // 将ZIP64 extra field添加到现有extra field的开头
                extra_field.extend_from_slice(&self.extra_field);
                self.extra_field = extra_field;
            }
        }
    }

    fn remove_zip64_extra_field(&mut self) {
        let mut new_extra_field = Vec::new();
        let mut offset = 0;

        while offset + 4 <= self.extra_field.len() {
            let header_id =
                u16::from_le_bytes([self.extra_field[offset], self.extra_field[offset + 1]]);
            let data_size =
                u16::from_le_bytes([self.extra_field[offset + 2], self.extra_field[offset + 3]])
                    as usize;

            if header_id != ZIP64_EXTRA_FIELD_ID {
                // 保留非ZIP64的extra field
                let end = offset + 4 + data_size;
                if end <= self.extra_field.len() {
                    new_extra_field.extend_from_slice(&self.extra_field[offset..end]);
                }
            }

            offset += 4 + data_size;
        }

        self.extra_field = new_extra_field;
    }

    // 设置文件注释
    pub fn set_comment(&mut self, comment: &str) {
        self.file_comment = comment.as_bytes().to_vec();
    }

    pub fn get_file_name(&self) -> String {
        String::from_utf8_lossy(&self.filename).to_string()
    }

    // 解析extra field中的ZIP64信息
    pub fn parse_zip64_extra_field(&mut self) -> anyhow::Result<()> {
        let mut offset = 0;

        while offset + 4 <= self.extra_field.len() {
            let header_id =
                u16::from_le_bytes([self.extra_field[offset], self.extra_field[offset + 1]]);
            let data_size =
                u16::from_le_bytes([self.extra_field[offset + 2], self.extra_field[offset + 3]])
                    as usize;

            if header_id == ZIP64_EXTRA_FIELD_ID {
                let data_start = offset + 4;
                let data_end = data_start + data_size;
                if data_end <= self.extra_field.len() {
                    let zip64_data = &self.extra_field[data_start..data_end];
                    self.zip64_extended_info = Some(Zip64ExtendedInfo::from_bytes(zip64_data)?);
                }
                break;
            }

            offset += 4 + data_size;
        }

        Ok(())
    }
}

// 归档文件基本信息结构体
#[derive(Debug, Default)]
pub struct ArchiveFileInfo {
    pub num_entries: u16,
    pub size: u32,
    pub offset: u32,
    pub comment: String,
    // ZIP64支持
    pub is_zip64: bool,
    pub zip64_num_entries: Option<u64>,
    pub zip64_size: Option<u64>,
    pub zip64_offset: Option<u64>,
}

impl ArchiveFileInfo {
    #[allow(dead_code)]
    pub fn new() -> Self {
        Self::default()
    }

    pub fn get_num_entries(&self) -> u64 {
        self.zip64_num_entries.unwrap_or(self.num_entries as u64)
    }

    #[allow(dead_code)]
    pub fn get_size(&self) -> u64 {
        self.zip64_size.unwrap_or(self.size as u64)
    }

    pub fn get_offset(&self) -> u64 {
        self.zip64_offset.unwrap_or(self.offset as u64)
    }

    pub fn set_zip64_info(&mut self, num_entries: u64, size: u64, offset: u64) {
        if archive_needs_zip64(num_entries as usize, size, offset) {
            self.is_zip64 = true;
            self.zip64_num_entries = Some(num_entries);
            self.zip64_size = Some(size);
            self.zip64_offset = Some(offset);

            // 设置标准字段为最大值或实际值
            self.num_entries = if num_entries > MAX_ZIP_ENTRIES as u64 {
                MAX_ZIP_ENTRIES
            } else {
                num_entries as u16
            };
            self.size = if size > MAX_ZIP_SIZE as u64 {
                MAX_ZIP_SIZE
            } else {
                size as u32
            };
            self.offset = if offset > MAX_ZIP_SIZE as u64 {
                MAX_ZIP_SIZE
            } else {
                offset as u32
            };
        } else {
            self.num_entries = num_entries as u16;
            self.size = size as u32;
            self.offset = offset as u32;
        }
    }
}

// 压缩编码器枚举
pub enum CompressionEncoder<W: Write + 'static> {
    Stored(W),
    Deflate(DeflateEncoder<W>),
    Bzip2(BzEncoder<W>),
    // 仅加密（无压缩）
    Encrypted(ZipCryptoEncryptor<W>),
    // 压缩+加密
    DeflateEncrypted(DeflateEncoder<ZipCryptoEncryptor<W>>),
    Bzip2Encrypted(BzEncoder<ZipCryptoEncryptor<W>>),
}
impl<W: Write + Seek + 'static> CompressionEncoder<W> {
    pub fn new(
        writer: W,
        method: CompressionMethod,
        level: u32,
        password: Option<&str>,
        crc32: u32,
    ) -> anyhow::Result<Self> {
        match (method, password) {
            (CompressionMethod::Stored, None) => Ok(Self::Stored(writer)),
            (CompressionMethod::Deflated, None) => Ok(Self::Deflate(DeflateEncoder::new(
                writer,
                Compression::new(level),
            ))),
            (CompressionMethod::Bzip2, None) => Ok(Self::Bzip2(BzEncoder::new(
                writer,
                bzip2::Compression::new(level),
            ))),
            (CompressionMethod::Stored, Some(pw)) => {
                Ok(Self::Encrypted(ZipCryptoEncryptor::new(writer, pw, crc32)?))
            }
            (CompressionMethod::Deflated, Some(pw)) => {
                let encryptor = ZipCryptoEncryptor::new(writer, pw, crc32)?;
                Ok(Self::DeflateEncrypted(DeflateEncoder::new(
                    encryptor,
                    Compression::new(level),
                )))
            }
            (CompressionMethod::Bzip2, Some(pw)) => {
                let encryptor = ZipCryptoEncryptor::new(writer, pw, crc32)?;
                Ok(Self::Bzip2Encrypted(BzEncoder::new(
                    encryptor,
                    bzip2::Compression::new(level),
                )))
            }
        }
    }
}

impl<W: Write + 'static> CompressionEncoder<W> {
    pub fn write_all(&mut self, data: &[u8]) -> anyhow::Result<()> {
        use CompressionEncoder::*;
        match self {
            Stored(w) => w.write_all(data)?,
            Deflate(e) => e.write_all(data)?,
            Bzip2(e) => e.write_all(data)?,
            Encrypted(e) => e.write_all(data)?,
            DeflateEncrypted(e) => e.write_all(data)?,
            Bzip2Encrypted(e) => e.write_all(data)?,
        }
        Ok(())
    }
    pub fn flush(&mut self) -> anyhow::Result<()> {
        use CompressionEncoder::*;
        match self {
            Stored(w) => w.flush()?,
            Deflate(e) => e.flush()?,
            Bzip2(e) => e.flush()?,
            Encrypted(e) => e.flush()?,
            DeflateEncrypted(e) => e.flush()?,
            Bzip2Encrypted(e) => e.flush()?,
        }
        Ok(())
    }
    pub fn finish(self) -> anyhow::Result<()> {
        use CompressionEncoder::*;
        match self {
            Stored(mut w) => {
                w.flush()?;
                Ok(())
            }
            Deflate(e) => {
                e.finish()?;
                Ok(())
            }
            Bzip2(e) => {
                e.finish()?;
                Ok(())
            }
            Encrypted(e) => {
                e.finish()?;
                Ok(())
            }
            DeflateEncrypted(e) => {
                e.finish()?.finish()?;
                Ok(())
            }
            Bzip2Encrypted(e) => {
                e.finish()?.finish()?;
                Ok(())
            }
        }
    }
    pub fn replace_writer(&mut self, new_writer: W) -> anyhow::Result<()> {
        use CompressionEncoder::*;
        match self {
            Stored(w) => {
                *w = new_writer;
            }
            Deflate(e) => {
                e.reset(new_writer)?;
            }
            Bzip2(e) => {
                *e = BzEncoder::new(new_writer, bzip2::Compression::new(9));
            }
            Encrypted(e) => {
                e.replace_writer(new_writer)?;
            }
            DeflateEncrypted(e) => {
                let enc = e.get_mut();
                enc.replace_writer(new_writer)?;
            }
            Bzip2Encrypted(e) => {
                let enc = e.get_mut();
                enc.replace_writer(new_writer)?;
            }
        }
        Ok(())
    }
}

// #[derive(Debug)]
struct CurrentFile<W: Write + Seek + 'static> {
    name: String,
    header_start: u64,
    data_start: u64,
    compression: CompressionMethod,
    flags: u16,
    password: Option<String>,
    hasher: Hasher,
    bytes_written: u64,
    encoder: Option<CompressionEncoder<W>>,

    mod_time: u16,
    mod_date: u16,
    external_attr: u32,
    disk_num: u16,
    extra_field: Vec<u8>,

    skip_compression: bool, // 是否跳过压缩,跳过后，下面的三个字段才有用
    compress_size: u32,     // 压缩后的大小
    uncompress_size: u64,   // 原始大小
    crc32: u32,             // 原始的crc32

    // 新增：标记压缩级别是否由外部显式指定，用于控制自动Store模式切换
    compression_level_specified: bool,

    // 用于自动切换到Store模式的原始数据缓冲区
    original_data_buffer: Vec<u8>,
    original_compression: CompressionMethod, // 保存原始压缩方法
}

// 压缩方法枚举
#[derive(Default, Clone, Copy, Debug, PartialEq)]
pub enum CompressionMethod {
    #[default]
    Stored = 0,
    Deflated = 8,
    Bzip2 = 12,
}

impl CompressionMethod {
    pub fn to_le_bytes(self) -> [u8; 2] {
        (self as u16).to_le_bytes()
    }

    pub fn from(num: u16) -> Self {
        match num {
            0 => Self::Stored,
            8 => Self::Deflated,
            12 => Self::Bzip2,
            _ => Self::Stored,
        }
    }
}

impl std::fmt::Display for CompressionMethod {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            CompressionMethod::Stored => write!(f, "stored"),
            CompressionMethod::Deflated => write!(f, "deflated"),
            CompressionMethod::Bzip2 => write!(f, "bzipped"),
        }
    }
}

// 新增枚举定义转换类型
#[derive(Debug, Clone, Copy)]
pub enum LineEndingConversion {
    None,
    LfToCrlf, // Unix -> Windows
    CrlfToLf, // Windows -> Unix
}

#[derive(Debug, Default, Clone)]
pub struct FileOptions {
    pub compression_method: CompressionMethod, // 压缩方法，8表示DEFLATE
    pub password: Option<String>,              // 可选密码
    pub compression_level: u32,                // 新增压缩级别字段
    pub modification_time: Option<(u16, u16)>, // 新增修改时间字段

    pub convert_lf_to_crlf: bool, // 是否将LF转换为CRLF
    pub convert_crlf_to_lf: bool, // 是否将CRLF转换为LF

    pub external_attr: u32,   // 文件属性
    pub extra_field: Vec<u8>, // 额外字段

    pub no_extra_field: bool, // 是否不使用额外字段
    pub store_symlinks: bool, // 是否存储符号链接

    pub no_compress_extensions: HashSet<String>, // 不压缩的文件扩展名列表

    pub skip_compression: bool, // 是否跳过压缩,跳过后，下面的三个字段才有用
    pub compress_size: u32,     // 压缩后的大小
    pub uncompress_size: u64,   // 原始大小
    pub crc32: u32,             // 原始的crc32

    // 新增：标记压缩级别是否由外部显式指定
    pub compression_level_specified: bool, // 压缩级别是否由外部指定
}

impl FileOptions {
    pub fn new() -> Self {
        Self {
            compression_method: CompressionMethod::Deflated, // DEFLATE压缩
            password: None,
            compression_level: 6, // 默认压缩级别为6
            modification_time: None,
            no_compress_extensions: HashSet::from([
                ".zip".to_string(),
                ".Z".to_string(),
                ".zoo".to_string(),
                ".arc".to_string(),
                ".arj".to_string(),
            ]),
            compression_level_specified: false, // 默认为未指定
            ..Default::default()
        }
    }

    pub fn set_file_path(&mut self, file_path: &PathBuf) -> anyhow::Result<()> {
        // 根据传入文件路径设置文件属性
        // 获取文件修改时间并转换为ZIP格式时间戳
        let (time, date) = get_file_modification_time(file_path)?;
        self.with_modification_time((time, date));

        if !self.no_extra_field {
            self.set_ut_extra_field(file_path)?;
        }
        self.with_file_attrs(file_path)?;

        if file_path.is_dir() {
            self.with_compression(CompressionMethod::Stored);
        }

        // 检查文件扩展名是否在不压缩列表中
        let extension = file_path.extension().map_or(String::new(), |e| {
            let ext = e.to_string_lossy();
            if ext.starts_with('.') {
                ext.to_string()
            } else {
                format!(".{}", ext)
            }
        });
        log::debug!(
            "extension: {:?}, no_compress_extensions: {:?}",
            extension,
            self.no_compress_extensions
        );
        if self.no_compress_extensions.contains(&extension) {
            self.with_compression(CompressionMethod::Stored);
        }

        if file_path.is_file() {
            let metadata = metadata(file_path)?;
            let file_size = metadata.len();
            self.uncompress_size = file_size;

            let crc32 = self.caculate_crc32(file_path)?;
            self.crc32 = crc32;

            // 根据文件大小动态优化压缩级别
            if self.compression_method == CompressionMethod::Deflated {
                self.optimize_compression_level_for_size(file_size);
            }

            log::debug!("File '{}' size: {} bytes", file_path.display(), file_size);
        }

        Ok(())
    }

    fn caculate_crc32(&self, file_path: &PathBuf) -> anyhow::Result<u32> {
        let mut hasher = Hasher::new();
        let mut file = File::open(file_path)?;
        let mut buffer = Box::new([0u8; 32 * 1024]); // 32KB buffer
        loop {
            let bytes_read = file.read(&mut *buffer)?;
            if bytes_read == 0 {
                break;
            }
            hasher.update(&buffer[..bytes_read]);
        }
        Ok(hasher.finalize())
    }

    pub fn get_line_ending_conversion(&mut self, is_text: bool) -> LineEndingConversion {
        if !is_text {
            return LineEndingConversion::None;
        }
        if self.convert_lf_to_crlf {
            LineEndingConversion::LfToCrlf
        } else if self.convert_crlf_to_lf {
            LineEndingConversion::CrlfToLf
        } else {
            LineEndingConversion::None
        }
    }

    pub fn with_password(&mut self, password: &str) {
        self.password = Some(password.to_string());
    }

    #[allow(dead_code)]
    pub fn with_skip_compression(&mut self, skip: bool) -> &mut Self {
        self.skip_compression = skip;
        self
    }

    pub fn with_compression(&mut self, method: CompressionMethod) {
        self.compression_method = method;

        // 只有在压缩级别未被外部指定时，才设置默认值
        if !self.compression_level_specified {
            if method == CompressionMethod::Stored {
                self.compression_level = 0; // 如果使用存储方法，则不需要压缩级别
            } else if method == CompressionMethod::Deflated {
                self.compression_level = 6; // 默认使用优化的压缩级别
            } else if method == CompressionMethod::Bzip2 {
                self.compression_level = 9; // Bzip2默认压缩级别
            }
        }
    }
    pub fn with_compression_level(&mut self, level: u32) {
        self.compression_level = level;
        self.compression_level_specified = true; // 标记为外部指定
    }

    // 根据文件大小优化压缩级别（仅在未外部指定时）
    pub fn optimize_compression_level_for_size(&mut self, file_size: u64) {
        // 如果压缩级别已经由外部指定，则不进行自动优化
        if self.compression_level_specified {
            log::debug!(
                "Compression level {} was externally specified, skipping optimization for {} bytes file",
                self.compression_level,
                file_size
            );
            return;
        }

        let original_level = self.compression_level;
        self.compression_level = match file_size {
            0..=100 => 1,        // 极小文件：最低级别，速度优先
            101..=1024 => 1,     // 小文件：级别1，最佳平衡点
            1025..=10240 => 2,   // 中小文件：级别2，稍好压缩
            10241..=102400 => 3, // 中等文件：级别3
            _ => 6,              // 大文件：标准级别，压缩比优先
        };

        log::debug!(
            "Auto-optimized compression level for {} bytes file: {} -> {}",
            file_size,
            original_level,
            self.compression_level
        );
    }

    fn with_modification_time(&mut self, time: (u16, u16)) {
        self.modification_time = Some(time);
    }

    //从实际文件获取权限
    fn with_file_attrs(&mut self, path: &Path) -> anyhow::Result<()> {
        use std::os::unix::fs::PermissionsExt;
        let metadata = metadata(path)?;
        let mode = metadata.permissions().mode();

        // 高16位: Unix属性 (文件类型+权限)
        // 低16位: DOS属性 (兼容Windows)
        self.external_attr =
            ((mode as u32 & 0xFFFF) << 16) | if metadata.is_dir() { 0x10 } else { 0x20 };

        Ok(())
    }

    // 获取utime时间戳
    fn set_ut_extra_field(&mut self, file_path: &Path) -> anyhow::Result<()> {
        let metadata = metadata(file_path)?;
        let mod_time = metadata
            .modified()?
            .duration_since(std::time::UNIX_EPOCH)?
            .as_secs() as u32;

        let mut field = Vec::with_capacity(7);
        field.extend_from_slice(&0x5455u16.to_le_bytes()); // Header ID
        field.extend_from_slice(&5u16.to_le_bytes()); // Data Size
        field.push(0x01); // Flags: modtime present
        field.extend_from_slice(&(mod_time as u32).to_le_bytes()); // modtime (UTC, u32)

        self.extra_field = field.clone();
        Ok(())
    }
}

// 压缩信息结构体,用于存储压缩文件的信息
#[derive(Debug)]
pub struct CompressionInfo {
    #[allow(dead_code)]
    pub name: String,
    pub method: CompressionMethod,
    pub original_size: u64,
    pub compressed_size: u64,
}

pub struct ZipWriter<'a> {
    file: File,
    cd_headers: Vec<CentralDirectoryHeader>,
    current_file: Option<CurrentFile<File>>,
    output_path: String,
    archive_info: ArchiveFileInfo,

    // 新增分卷支持
    split_size: Option<u64>,  // 分卷大小
    current_split_index: u16, // 当前分卷索引
    base_name: String,        // 基础文件名
    // 回调函数，用于在每个分卷完成后调用
    split_callback: Option<Box<dyn FnMut(u16) -> anyhow::Result<PathBuf> + 'a>>,
    split_bell: bool,    // 是否响铃
    split_verbose: bool, // 是否显示分卷的详细输出
}

impl<'a> ZipWriter<'a> {
    pub fn new(output_path: &str) -> anyhow::Result<Self> {
        log::info!("create zip writer: {}", output_path);

        let writer = Self {
            file: File::create(output_path)?,
            cd_headers: Vec::new(),
            current_file: None,
            output_path: output_path.to_string(),
            archive_info: ArchiveFileInfo::default(),
            split_size: None,
            current_split_index: 1,
            base_name: output_path.to_string(),
            split_callback: None,
            split_bell: false,
            split_verbose: false,
        };

        Ok(writer)
    }

    pub fn get_split_name(&self) -> Option<String> {
        if self.current_split_index > 1 {
            let new_path = format!("{}.z{:02}", self.base_name, self.current_split_index);
            return Some(new_path);
        }
        None
    }

    fn get_base_name(path: &str) -> String {
        let path = Path::new(path);
        let parent = path.parent().map(|p| p.to_string_lossy().into_owned());
        let stem = path.file_stem().map(|s| s.to_string_lossy().into_owned());

        match (parent, stem) {
            (Some(parent_path), Some(stem_name)) => {
                if parent_path.is_empty() {
                    stem_name
                } else {
                    format!("{}/{}", parent_path, stem_name)
                }
            }
            (None, Some(stem_name)) => stem_name,
            _ => path.to_string_lossy().into_owned(),
        }
    }

    pub fn get_current_split_index(&self) -> u16 {
        self.current_split_index
    }

    /// 获取当前文件的压缩字节数
    pub fn get_current_file_compressed_bytes(&mut self) -> u64 {
        if let Some(current) = &self.current_file {
            let current_pos = self.file.stream_position().unwrap_or(0);

            // 计算当前分卷已写入的字节数：如果流位置小于 data_start，说明 data_start 是首卷偏移，
            // 直接使用 current_pos；否则减去 data_start。
            let bytes_this_split = if current_pos >= current.data_start {
                current_pos - current.data_start
            } else {
                current_pos
            };

            if current.disk_num != self.current_split_index {
                // 文件已跨分卷，先加上前面分卷累计的大小
                current.compress_size as u64 + bytes_this_split
            } else {
                bytes_this_split
            }
        } else {
            0
        }
    }

    pub fn set_split_args(
        &mut self,
        split_size: Option<u64>,
        bell: bool,
        verbose: bool,
    ) -> anyhow::Result<()> {
        self.split_size = split_size;
        self.split_bell = bell;
        self.split_verbose = verbose;

        if let Some(size) = split_size {
            log::info!("split size: {} bytes", size);
            self.base_name = Self::get_base_name(&self.output_path);
            log::debug!("base name: {}", self.base_name);

            // 为第一个分卷写入多卷签名
            self.file.write_all(&[0x50, 0x4B, 0x07, 0x08])?; // 多卷签名
        }
        Ok(())
    }

    pub fn set_split_callback<F>(&mut self, callback: F)
    where
        F: FnMut(u16) -> anyhow::Result<PathBuf> + 'a,
    {
        self.split_callback = Some(Box::new(callback));
    }

    /// 更新基础名称以用于输出文件（用于分割文件命名）
    pub fn update_base_name_for_output(&mut self, final_output_path: &str) {
        self.base_name = Self::get_base_name(final_output_path);
        log::info!("Updated base_name for split files to: {}", self.base_name);
    }

    #[allow(dead_code)]
    pub fn seek(&mut self, offset: u64) -> io::Result<u64> {
        self.file.seek(io::SeekFrom::Start(offset))
    }

    pub fn get_file_stream_position(&mut self) -> io::Result<u64> {
        self.file.stream_position()
    }

    #[allow(dead_code)]
    pub fn get_output_path(&self) -> &str {
        &self.output_path
    }

    pub fn start_file(&mut self, name: &str, options: FileOptions) -> anyhow::Result<()> {
        // 如果当前有文件正在写入，先完成它
        if self.current_file.is_some() {
            self.finish_file()?;
        }

        log::info!(
            "start file: {}, method: {:?}, crc32: {}",
            name,
            options.compression_method,
            options.crc32
        );

        let flags = if options.password.is_some() {
            ZIP_CRYPTO_FLAG
        } else {
            0
        };

        // 获取文件修改时间并转换为 ZIP 格式
        let (mod_time, mod_date) = if let Some((time, date)) = options.modification_time {
            (time, date)
        } else {
            let now = Local::now();
            Self::datetime_to_zip_format(&now)
        };

        let header_start = self.file.stream_position()?;

        // 检查是否需要ZIP64格式（基于文件大小和位置）
        let needs_zip64_file = if options.skip_compression {
            // 对于已知大小的文件，直接检查是否需要ZIP64
            needs_zip64(
                options.uncompress_size,
                options.compress_size as u64,
                header_start,
                0,
            )
        } else {
            // 对于实时压缩的文件，检查原始大小和位置
            let uncompressed_size = options.uncompress_size;
            // 如果原始文件大于4GB或位置超过4GB，使用ZIP64
            uncompressed_size > MAX_ZIP_SIZE as u64 || header_start > MAX_ZIP_SIZE as u64
        };

        let mut lfh = LocalFileHeader {
            version_needed: if needs_zip64_file {
                VERSION_NEEDED_ZIP64
            } else {
                VERSION_NEEDED
            },
            flags,
            compression: options.compression_method,
            mod_time,
            mod_date,
            crc32: options.crc32, // 临时值，将在finish时更新
            compressed_size: 0,   // 临时值
            uncompressed_size: 0, // 临时值
            filename: name.as_bytes().to_vec(),
            extra_field: options.extra_field.clone(),
            zip64_extended_info: None,
        };

        // 如果需要ZIP64，设置ZIP64信息
        if needs_zip64_file {
            lfh.set_zip64_info(options.uncompress_size, options.compress_size as u64);
            log::debug!("File '{}' will use ZIP64 format", name);
        }
        // 写入本地文件头
        self.write_local_header(&lfh)?;

        // 记录数据开始位置
        let data_start = self.file.stream_position()?;

        // 创建编码器
        let method = if options.skip_compression {
            // 不压缩，使用原始大小
            CompressionMethod::Stored
        } else {
            options.compression_method
        };
        let encoder = CompressionEncoder::new(
            self.file.try_clone()?,
            method,
            options.compression_level,
            options.password.as_deref(),
            options.crc32,
        )?;

        self.current_file = Some(CurrentFile {
            name: name.to_string(),
            header_start,
            data_start,
            compression: options.compression_method,
            flags,
            password: options.password,
            hasher: Hasher::new(),
            bytes_written: 0,
            encoder: Some(encoder),
            disk_num: self.current_split_index,
            mod_time,
            mod_date,
            external_attr: options.external_attr, // 传递文件属性
            extra_field: options.extra_field.clone(), // 传递额外字段
            skip_compression: options.skip_compression,
            compress_size: options.compress_size,
            uncompress_size: options.uncompress_size,
            crc32: options.crc32,
            compression_level_specified: options.compression_level_specified, // 传递压缩级别是否外部指定的标志
            original_data_buffer: Vec::new(),
            original_compression: options.compression_method, // 保存原始压缩方法
        });
        Ok(())
    }

    pub fn write_all(&mut self, mut data: &[u8]) -> anyhow::Result<()> {
        // 校验当前状态
        if self.current_file.is_none() {
            return Err(anyhow::anyhow!("No file is currently open for writing"));
        }
        if self.current_file.as_ref().unwrap().encoder.is_none() {
            return Err(anyhow::anyhow!("Encoder not initialized"));
        }

        // 未启用分卷时直接写入并返回
        if self.split_size.is_none() {
            {
                let current_mut = self.current_file.as_mut().unwrap();
                let enc = current_mut.encoder.as_mut().unwrap();
                enc.write_all(data)?;
                enc.flush()?;
                // 记录原始数据以备后续计算（如 CRC、压缩判定等）
                current_mut.hasher.update(data);
                current_mut.bytes_written += data.len() as u64;

                if current_mut.original_data_buffer.len() < 32 * 1024 {
                    let remain = 32 * 1024 - current_mut.original_data_buffer.len();
                    current_mut
                        .original_data_buffer
                        .extend_from_slice(&data[..std::cmp::min(remain, data.len())]);
                }

                let end_pos = self.file.stream_position()?;
                current_mut.compress_size = (end_pos - current_mut.data_start) as u32;
            }
            return Ok(());
        }

        let split_size = self.split_size.unwrap();
        const CHUNK: usize = 8 * 1024; // 每次写入的最大块大小
        const OVERHEAD: u64 = 12; // DEFLATE 每次 flush 可能额外产生 ~12 字节

        while !data.is_empty() {
            // 先检查当前分卷是否已满
            let current_pos = self.file.stream_position()?;

            // 如果当前分卷已满，提前切换
            if current_pos >= split_size {
                self.switch_to_next_split()?;
                // 切换后更新 encoder 的底层 writer
                {
                    let current_mut = self.current_file.as_mut().unwrap();
                    current_mut
                        .encoder
                        .as_mut()
                        .unwrap()
                        .replace_writer(self.file.try_clone()?)?;
                }
                continue;
            }

            let remaining = split_size - current_pos;
            if remaining <= OVERHEAD {
                // 剩余空间不足以容纳安全余量，提前切卷
                self.switch_to_next_split()?;
                {
                    let current_mut = self.current_file.as_mut().unwrap();
                    current_mut
                        .encoder
                        .as_mut()
                        .unwrap()
                        .replace_writer(self.file.try_clone()?)?;
                }
                continue;
            }

            let available = if remaining > OVERHEAD {
                (remaining - OVERHEAD) as usize
            } else {
                0
            };

            if available == 0 {
                // 理论上不会发生，但为了安全再次切卷
                self.switch_to_next_split()?;
                {
                    let current_mut = self.current_file.as_mut().unwrap();
                    current_mut
                        .encoder
                        .as_mut()
                        .unwrap()
                        .replace_writer(self.file.try_clone()?)?;
                }
                continue;
            }

            let mut write_len = std::cmp::min(data.len(), available);
            if write_len > CHUNK {
                write_len = CHUNK;
            }

            {
                // 限定作用域，确保 encoder 的可变借用不会与后续的 &mut self 冲突
                let current_mut = self.current_file.as_mut().unwrap();
                let encoder_ref = current_mut.encoder.as_mut().unwrap();
                encoder_ref.write_all(&data[..write_len])?;
                encoder_ref.flush()?; // 每块 flush，确保文件位置准确

                // 更新哈希、原始大小计数及32KB缓冲
                {
                    let current_mut_inner = self.current_file.as_mut().unwrap();
                    current_mut_inner.hasher.update(&data[..write_len]);
                    current_mut_inner.bytes_written += write_len as u64;

                    if current_mut_inner.original_data_buffer.len() < 32 * 1024 {
                        let remain = 32 * 1024 - current_mut_inner.original_data_buffer.len();
                        current_mut_inner
                            .original_data_buffer
                            .extend_from_slice(&data[..std::cmp::min(remain, write_len)]);
                    }
                }
            }

            let current_end_pos = self.file.stream_position()?;
            let bytes_written = current_end_pos - current_pos;
            {
                let current_mut = self.current_file.as_mut().unwrap();
                current_mut.compress_size += bytes_written as u32;
            }
            data = &data[write_len..];

            // 如果正好写满一个分卷，立即切换
            if current_end_pos == split_size {
                self.switch_to_next_split()?;
                {
                    let current_mut = self.current_file.as_mut().unwrap();
                    current_mut
                        .encoder
                        .as_mut()
                        .unwrap()
                        .replace_writer(self.file.try_clone()?)?;
                }
            }
        }
        Ok(())
    }

    // 原始数据直接写入文件
    pub fn inner_write_all(&mut self, data: &[u8]) -> anyhow::Result<()> {
        self.file.write_all(data)?;
        self.file.flush()?;
        Ok(())
    }

    pub fn finish(&mut self) -> anyhow::Result<()> {
        // 确保当前文件已完成
        if self.current_file.is_some() {
            self.finish_file()?;
        }

        // 写入中央目录
        let cd_start = self.file.stream_position()?;
        let headers = self.cd_headers.clone(); // Clone headers to avoid immutable borrow
        for header in &headers {
            self.write_central_directory_header(header)?;
        }
        let cd_end = self.file.stream_position()?;
        let cd_size = cd_end - cd_start;

        // 检查是否需要ZIP64格式
        let total_entries = self.cd_headers.len();
        let needs_zip64 = archive_needs_zip64(total_entries, cd_size, cd_start);

        if needs_zip64 {
            // 记录ZIP64结束目录记录的开始位置
            let zip64_end_offset = self.file.stream_position()?;

            // 写入ZIP64结束目录记录
            self.write_zip64_end_of_central_directory(total_entries as u64, cd_size, cd_start)?;

            // 写入ZIP64结束目录定位器
            self.write_zip64_end_of_central_directory_locator(zip64_end_offset)?;
        }

        // 设置归档信息
        self.archive_info
            .set_zip64_info(total_entries as u64, cd_size, cd_start);

        // 写入标准结束记录（兼容性）
        self.write_end_of_central_directory()?;

        self.file.flush()?;

        // 处理分割文件的最终重命名
        if let Some(split_size) = self.split_size {
            // 检查文件是否真正需要分割
            let file_size = self.file.metadata()?.len();
            let actually_split = self.current_split_index > 1 || file_size >= split_size;

            if actually_split {
                if self.current_split_index == 1 {
                    // 如果只有一个分割文件，但文件大小超过分割大小，需要重命名为 .z01
                    let new_path = format!("{}.z{:02}", self.base_name, self.current_split_index);
                    std::fs::rename(&self.output_path, &new_path)?;
                    if self.split_verbose {
                        println!("      Closing split {}", new_path);
                    }
                    log::info!("Renamed single split file to: {}", new_path);
                } else {
                    // 多个分割文件，最后一个保持 .zip 扩展名
                    if self.split_verbose {
                        println!("      Closing split {}", self.output_path);
                    }
                }
            } else {
                // 文件不需要分割，保持普通的 .zip 扩展名
                log::info!(
                    "File size {} is smaller than split size {}, keeping as regular ZIP",
                    file_size,
                    split_size
                );
            }
        }

        log::info!(
            "ZIP archive completed, total entries: {}, ZIP64: {}, splits: {}",
            total_entries,
            needs_zip64,
            self.current_split_index
        );
        Ok(())
    }

    // 写入ZIP64结束目录记录
    fn write_zip64_end_of_central_directory(
        &mut self,
        total_entries: u64,
        cd_size: u64,
        cd_offset: u64,
    ) -> anyhow::Result<()> {
        let mut record = Zip64EndOfCentralDir {
            entries_on_disk: total_entries,
            total_entries,
            central_dir_size: cd_size,
            central_dir_offset: cd_offset,
            ..Default::default()
        };

        // 如果使用分卷，设置磁盘信息
        if self.split_size.is_some() {
            record.disk_number = (self.current_split_index - 1) as u32;
            record.central_dir_disk = (self.current_split_index - 1) as u32;
        }

        // 写入ZIP64结束目录记录签名
        self.file.write_all(&[0x50, 0x4B, 0x06, 0x06])?;

        // 写入记录
        self.file.write_all(&record.size_of_record.to_le_bytes())?;
        self.file.write_all(&record.version_made.to_le_bytes())?;
        self.file.write_all(&record.version_needed.to_le_bytes())?;
        self.file.write_all(&record.disk_number.to_le_bytes())?;
        self.file
            .write_all(&record.central_dir_disk.to_le_bytes())?;
        self.file.write_all(&record.entries_on_disk.to_le_bytes())?;
        self.file.write_all(&record.total_entries.to_le_bytes())?;
        self.file
            .write_all(&record.central_dir_size.to_le_bytes())?;
        self.file
            .write_all(&record.central_dir_offset.to_le_bytes())?;

        log::debug!("Wrote ZIP64 end of central directory record");
        Ok(())
    }

    // 写入ZIP64结束目录定位器
    fn write_zip64_end_of_central_directory_locator(
        &mut self,
        zip64_end_offset: u64,
    ) -> anyhow::Result<()> {
        let mut locator = Zip64EndOfCentralDirLocator {
            zip64_end_offset,
            ..Default::default()
        };

        if self.split_size.is_some() {
            locator.central_dir_disk = (self.current_split_index - 1) as u32;
            locator.total_disks = self.current_split_index as u32;
        }

        // 写入ZIP64结束目录定位器签名
        self.file.write_all(&[0x50, 0x4B, 0x06, 0x07])?;

        // 写入定位器
        self.file
            .write_all(&locator.central_dir_disk.to_le_bytes())?;
        self.file
            .write_all(&locator.zip64_end_offset.to_le_bytes())?;
        self.file.write_all(&locator.total_disks.to_le_bytes())?;

        log::debug!("Wrote ZIP64 end of central directory locator");
        Ok(())
    }

    // 设置归档注释
    pub fn set_archive_comment(&mut self, comment: &str) {
        self.archive_info.comment = comment.to_owned();
    }

    // 获取中央目录头的引用，以便外部修改
    pub fn central_directory_headers_mut(&mut self) -> &mut Vec<CentralDirectoryHeader> {
        &mut self.cd_headers
    }

    // 添加中央目录头
    pub fn add_central_directory_header(&mut self, header: CentralDirectoryHeader) {
        self.cd_headers.push(header);
    }

    pub fn finish_into_readable(&mut self) -> anyhow::Result<ZipArchive> {
        self.finish()?;

        let archive = ZipArchive::new(&self.output_path)?;
        Ok(archive)
    }

    // 将日期时间转换为 ZIP 格式的时间戳
    fn datetime_to_zip_format(dt: &chrono::DateTime<Local>) -> (u16, u16) {
        let time = ((dt.hour() as u16) << 11)    // 小时占5位(11-15)
                 | ((dt.minute() as u16) << 5)   // 分钟占6位(5-10)
                 | ((dt.second() as u16) >> 1); // 秒/2占5位(0-4)

        let date = (((dt.year() - 1980) as u16) << 9)  // 年从1980开始，占7位(9-15)
                 | ((dt.month() as u16) << 5)          // 月占4位(5-8)
                 | (dt.day() as u16); // 日占5位(0-4)

        (time, date)
    }

    pub fn finish_file(&mut self) -> anyhow::Result<CompressionInfo> {
        let mut current = self
            .current_file
            .take()
            .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "No current file to finish"))?;

        let (crc32, orgin_size) = if current.skip_compression {
            log::debug!(
                "skip compression, use original size: {} crc32: {}",
                current.uncompress_size,
                current.crc32
            );
            (current.crc32, current.uncompress_size)
        } else {
            let crc32 = current.hasher.clone().finalize();

            (crc32, current.bytes_written)
        };

        let mut compressed_size = if let Some(encoder) = current.encoder.take() {
            // 完成压缩
            encoder.finish()?;
            if current.disk_num != self.current_split_index {
                current.compress_size += (self.file.stream_position()? - current.data_start) as u32;
                current.compress_size as u64
            } else {
                self.file.stream_position()? - current.data_start
            }
        } else if current.skip_compression {
            current.compress_size as u64
        } else {
            current.bytes_written
        };

        // 检查是否需要切换到Store模式
        // 只有当我们有完整的原始数据缓冲区时才执行切换（即文件大小 <= 32KB）
        if !current.skip_compression
            && current.original_compression != CompressionMethod::Stored
            && !current.compression_level_specified
            && !current.original_data_buffer.is_empty()
            && current.original_data_buffer.len() as u64 == orgin_size  // 确保我们有完整的数据
            && compressed_size >= orgin_size
        {
            log::info!(
                "Compression ineffective: compressed size {} >= original size {}, switching to Store mode",
                compressed_size,
                orgin_size
            );

            // 重新定位到数据开始位置并截断文件
            self.file.seek(io::SeekFrom::Start(current.data_start))?;
            self.file.set_len(current.data_start)?;

            // 切换到Store模式
            current.compression = CompressionMethod::Stored;

            // 创建新的Store模式encoder
            let mut store_encoder = CompressionEncoder::new(
                self.file.try_clone()?,
                CompressionMethod::Stored,
                0,
                current.password.as_deref(),
                crc32,
            )?;

            // 使用缓冲的原始数据重新写入
            store_encoder.write_all(&current.original_data_buffer)?;
            store_encoder.finish()?;
            let current_end_pos = self.file.stream_position()?;
            // 更新压缩大小
            compressed_size = current_end_pos - current.data_start;
            current.compress_size = compressed_size as u32;

            log::debug!(
                "Switched to Store mode: wrote {} bytes uncompressed",
                compressed_size
            );
        } else if !current.skip_compression
            && current.original_compression != CompressionMethod::Stored
            && !current.compression_level_specified
            && orgin_size > 32 * 1024
            && compressed_size >= orgin_size
        {
            log::warn!(
                "File size {} bytes exceeds 32KB buffer limit, cannot auto-switch to Store mode. \
                Consider using --store option for large incompressible files.",
                orgin_size
            );
        }

        // 检查是否需要ZIP64格式
        let needs_zip64_file = needs_zip64(orgin_size, compressed_size, current.header_start, 0);

        if current.disk_num != self.current_split_index {
            // 如果当前文件的分卷索引与当前分卷索引不一致，
            let original_path = format!("{}.z{:02}", self.base_name, current.disk_num);
            let mut original_file = File::options().read(true).write(true).open(original_path)?;

            if needs_zip64_file {
                // 对于ZIP64文件，需要重写整个本地文件头
                let header_start = current.header_start;
                let compression = current.compression;

                // 更新版本号为ZIP64
                original_file.seek(io::SeekFrom::Start(header_start + 4))?;
                original_file.write_all(&VERSION_NEEDED_ZIP64.to_le_bytes())?;

                // 更新压缩方法
                original_file.seek(io::SeekFrom::Start(header_start + 8))?;
                original_file.write_all(&compression.to_le_bytes())?;

                // 更新CRC和大小字段
                original_file.seek(io::SeekFrom::Start(header_start + 14))?;
                original_file.write_all(&crc32.to_le_bytes())?;

                // 对于ZIP64，如果大小超过32位限制，设置为最大值
                let compressed_32 = if compressed_size > MAX_ZIP_SIZE as u64 {
                    MAX_ZIP_SIZE
                } else {
                    compressed_size as u32
                };
                let uncompressed_32 = if orgin_size > MAX_ZIP_SIZE as u64 {
                    MAX_ZIP_SIZE
                } else {
                    orgin_size as u32
                };

                original_file.write_all(&compressed_32.to_le_bytes())?;
                original_file.write_all(&uncompressed_32.to_le_bytes())?;

                log::debug!(
                    "Updated split file local header for ZIP64: compressed={}, uncompressed={}",
                    compressed_size,
                    orgin_size
                );
            } else {
                // 更新原始分卷中的本地头
                original_file.seek(io::SeekFrom::Start(current.header_start + 8))?;
                original_file.write_all(&current.compression.to_le_bytes())?;
                original_file.seek(io::SeekFrom::Start(current.header_start + 14))?;
                original_file.write_all(&crc32.to_le_bytes())?;
                original_file.write_all(&(compressed_size as u32).to_le_bytes())?;
                original_file.write_all(&(orgin_size as u32).to_le_bytes())?;
            }
        } else {
            // 更新本地文件头中的CRC和大小信息
            let current_pos = self.file.stream_position()?;

            // 更新压缩方法
            self.file
                .seek(io::SeekFrom::Start(current.header_start + 8))?;
            self.file.write_all(&current.compression.to_le_bytes())?;

            // 更新CRC和大小字段
            self.file
                .seek(io::SeekFrom::Start(current.header_start + 14))?;
            self.file.write_all(&crc32.to_le_bytes())?;

            if needs_zip64_file {
                // 对于ZIP64，如果大小超过32位限制，设置为最大值
                let compressed_32 = if compressed_size > MAX_ZIP_SIZE as u64 {
                    MAX_ZIP_SIZE
                } else {
                    compressed_size as u32
                };
                let uncompressed_32 = if orgin_size > MAX_ZIP_SIZE as u64 {
                    MAX_ZIP_SIZE
                } else {
                    orgin_size as u32
                };
                self.file.write_all(&compressed_32.to_le_bytes())?;
                self.file.write_all(&uncompressed_32.to_le_bytes())?;

                // 更新本地文件头中的ZIP64额外字段
                let saved_pos = self.file.stream_position()?;
                let extra_field_start = current.header_start + 30 + current.name.len() as u64;

                // 创建更新后的ZIP64信息
                let mut updated_lfh = LocalFileHeader::new();
                updated_lfh.set_zip64_info(orgin_size, compressed_size);

                // 更新ZIP64额外字段
                self.file.seek(io::SeekFrom::Start(extra_field_start))?;
                self.file.write_all(&updated_lfh.extra_field)?;

                // 恢复文件指针
                self.file.seek(io::SeekFrom::Start(saved_pos))?;

                log::debug!(
                    "Updated local header with ZIP64 sizes: compressed={}, uncompressed={}",
                    compressed_size,
                    orgin_size
                );
            } else {
                // 标准格式，直接写入大小
                self.file
                    .write_all(&(compressed_size as u32).to_le_bytes())?;
                self.file.write_all(&(orgin_size as u32).to_le_bytes())?;
            }

            // 恢复文件指针位置
            self.file.seek(io::SeekFrom::Start(current_pos))?;
        }

        // 创建中央目录记录
        let mut cdh = CentralDirectoryHeader {
            version_made: if needs_zip64_file {
                ZIP64_VERSION_MADE
            } else {
                VERSION_MADE
            },
            version_needed: if needs_zip64_file {
                VERSION_NEEDED_ZIP64
            } else {
                VERSION_NEEDED
            },
            flags: current.flags,
            compression: current.compression,
            mod_time: current.mod_time,
            mod_date: current.mod_date,
            crc32,
            compressed_size: if compressed_size > MAX_ZIP_SIZE as u64 {
                MAX_ZIP_SIZE
            } else {
                compressed_size as u32
            },
            uncompressed_size: if orgin_size > MAX_ZIP_SIZE as u64 {
                MAX_ZIP_SIZE
            } else {
                orgin_size as u32
            },
            filename: current.name.as_bytes().to_vec(),
            extra_field: current.extra_field.clone(),
            file_comment: Vec::new(),
            disk_num: current.disk_num - 1, // 分卷索引从0开始
            internal_attr: 0,
            external_attr: current.external_attr,
            local_header_offset: if current.header_start > MAX_ZIP_SIZE as u64 {
                MAX_ZIP_SIZE
            } else {
                current.header_start as u32
            },
            zip64_extended_info: None,
        };

        // 如果需要ZIP64，设置ZIP64信息
        if needs_zip64_file {
            cdh.set_zip64_info(orgin_size, compressed_size, current.header_start);
            log::debug!("File '{}' requires ZIP64 format", current.name);
        }

        self.cd_headers.push(cdh);

        self.file.flush()?;

        Ok(CompressionInfo {
            name: current.name,
            method: current.compression,
            original_size: current.bytes_written,
            compressed_size,
        })
    }

    /// 添加一个目录到ZIP文件中
    pub fn add_directory(&mut self, name: String, options: FileOptions) -> anyhow::Result<()> {
        // 确保目录名以/结尾
        let dir_name = if name.ends_with('/') {
            name.to_string()
        } else {
            format!("{}/", name)
        };

        self.start_file(&dir_name, options)?;

        // 立即完成文件写入(目录没有数据)
        self.finish_file()?;

        Ok(())
    }

    /// 直接二进制拷贝文件(不修改加密数据)
    pub fn raw_copy_file(&mut self, source_file: &ZipFile, new_name: String) -> anyhow::Result<()> {
        // 确定新文件名
        let old_file_name = source_file.name();
        let target_name = if new_name.is_empty() {
            old_file_name
        } else {
            new_name
        };

        // 记录写入前的偏移，作为新local_header_offset
        let offset = self.file.stream_position()?;

        // 直接写入整个条目数据，不调用start_file
        self.copy_data(source_file)?;

        // 创建中央目录记录
        let cdh = CentralDirectoryHeader {
            version_made: source_file.header.version_made,
            version_needed: source_file.header.version_needed,
            flags: source_file.header.flags,
            compression: source_file.header.compression,
            mod_time: source_file.header.mod_time,
            mod_date: source_file.header.mod_date,
            crc32: source_file.header.crc32,
            compressed_size: source_file.header.compressed_size,
            uncompressed_size: source_file.header.uncompressed_size,
            filename: target_name.as_bytes().to_vec(), // 使用新文件名
            extra_field: source_file.header.extra_field.clone(),
            file_comment: source_file.header.file_comment.clone(),
            disk_num: source_file.header.disk_num,
            internal_attr: source_file.header.internal_attr,
            external_attr: source_file.header.external_attr,
            local_header_offset: offset as u32,
            zip64_extended_info: source_file.header.zip64_extended_info.clone(),
        };

        self.cd_headers.push(cdh);

        Ok(())
    }

    // 拷贝压缩后的数据 (修改加密数据)
    #[allow(dead_code)]
    pub fn add_raw_file(
        &mut self,
        entry: &ZipFile,
        mut options: &mut FileOptions,
        data: &[u8],
    ) -> anyhow::Result<()> {
        options = options.with_skip_compression(true);

        self.start_file(&entry.name(), options.clone())?;
        if entry.is_dir() {
            self.finish_file()?;
            return Ok(());
        }
        self.write_all(data)?;
        self.finish_file()?;

        Ok(())
    }

    /// 拷贝数据块从源文件到目标写入器
    fn copy_data(&mut self, zip_file: &ZipFile) -> anyhow::Result<()> {
        // 计算需要复制的数据范围
        let data_start = zip_file.header.get_local_header_offset();
        let data_length = zip_file.data_end.saturating_sub(data_start);

        // 首先尝试直接从文件读取（适用于单文件ZIP）
        let mut file = zip_file.file.try_clone()?;

        // 检查文件大小，如果数据超出文件范围，说明这是分割文件
        let file_size = file.metadata()?.len();

        if data_start + data_length > file_size {
            // 这是分割文件，我们需要使用分割文件读取逻辑
            log::debug!("Detected split archive, using split file reading logic");

            // 尝试检测分割文件模式
            let file_path = format!("/proc/self/fd/{}", file.as_raw_fd());
            let real_path = std::fs::read_link(&file_path)
                .unwrap_or_else(|_| std::path::PathBuf::from("unknown"));

            if let Some(path_str) = real_path.to_str() {
                if let Ok(split_data) = self.read_split_file_data(path_str, data_start, data_length)
                {
                    self.file.write_all(&split_data)?;
                    self.file.flush()?;
                    return Ok(());
                }
            }

            // 如果分割文件读取失败，返回错误
            return Err(anyhow::anyhow!(
                "Cannot copy from split archive: file spans multiple volumes. \
                 This is a limitation when copying from split archives. \
                 Please extract the file first or use a single ZIP file."
            ));
        }

        // 单文件ZIP的正常处理
        file.seek(SeekFrom::Start(data_start))?;

        let mut remaining = data_length;
        let mut buffer = vec![0u8; 1024 * 1024]; // 1MB缓冲区

        while remaining > 0 {
            let chunk_size = std::cmp::min(remaining as usize, buffer.len());
            let chunk = &mut buffer[..chunk_size];

            file.read_exact(chunk)?;
            self.inner_write_all(chunk)?;

            remaining -= chunk_size as u64;
        }
        self.file.flush()?;
        Ok(())
    }

    /// 从分割文件中读取数据的辅助方法
    fn read_split_file_data(
        &self,
        file_path: &str,
        offset: u64,
        length: u64,
    ) -> anyhow::Result<Vec<u8>> {
        // 获取基础文件名
        let base_name = if let Some(stripped) = file_path.strip_suffix(".zip") {
            stripped
        } else if file_path.contains(".z") {
            // 处理 .z01, .z02 等格式
            let parts: Vec<&str> = file_path.rsplitn(2, ".z").collect();
            if parts.len() == 2 {
                parts[1]
            } else {
                return Err(anyhow::anyhow!("Invalid split archive name format"));
            }
        } else {
            file_path
        };

        // 查找所有分割文件
        let mut split_files = Vec::new();

        // 添加 .z01, .z02, ... 文件
        for i in 1..=999 {
            let split_path = format!("{}.z{:02}", base_name, i);
            if std::path::Path::new(&split_path).exists() {
                split_files.push(split_path);
            } else {
                break;
            }
        }

        // 添加最后的 .zip 文件
        let final_path = format!("{}.zip", base_name);
        if std::path::Path::new(&final_path).exists() {
            split_files.push(final_path);
        }

        if split_files.is_empty() {
            return Err(anyhow::anyhow!("No split files found"));
        }

        // 使用与ZipArchive相同的分割文件读取逻辑
        let mut result = Vec::new();
        let mut remaining = length;
        let current_offset = offset;

        // 计算每个分割文件的大小
        let mut split_sizes = Vec::new();
        for split_path in &split_files {
            let metadata = std::fs::metadata(split_path)
                .with_context(|| format!("Failed to get metadata for: {}", split_path))?;
            split_sizes.push(metadata.len());
        }

        // 找到起始分割文件
        let mut cumulative_size = 0u64;
        let mut start_split_index = 0;
        let mut offset_in_split = current_offset;

        for (i, &size) in split_sizes.iter().enumerate() {
            if current_offset < cumulative_size + size {
                start_split_index = i;
                offset_in_split = current_offset - cumulative_size;
                break;
            }
            cumulative_size += size;
        }

        // 从起始分割文件开始读取
        for split_index in start_split_index..split_files.len() {
            if remaining == 0 {
                break;
            }

            let split_path = &split_files[split_index];
            let mut split_file = std::fs::File::open(split_path)
                .with_context(|| format!("Failed to open split file: {}", split_path))?;

            // 定位到正确的偏移量
            split_file.seek(io::SeekFrom::Start(offset_in_split))?;

            // 计算在这个分割文件中要读取的字节数
            let available_in_split = split_sizes[split_index] - offset_in_split;
            let to_read = std::cmp::min(remaining, available_in_split);

            // 读取数据
            let mut buffer = vec![0u8; to_read as usize];
            split_file.read_exact(&mut buffer)?;
            result.extend_from_slice(&buffer);

            remaining -= to_read;
            offset_in_split = 0; // 后续分割文件从开头开始读取
        }

        if remaining > 0 {
            return Err(anyhow::anyhow!(
                "Could not read all requested data from split files"
            ));
        }

        Ok(result)
    }

    // 辅助函数：写入本地文件头
    fn write_local_header(&mut self, header: &LocalFileHeader) -> anyhow::Result<()> {
        self.file.write_all(&[0x50, 0x4B, 0x03, 0x04])?; // 签名
        self.file.write_all(&header.version_needed.to_le_bytes())?;
        self.file.write_all(&header.flags.to_le_bytes())?;
        self.file.write_all(&header.compression.to_le_bytes())?;
        self.file.write_all(&header.mod_time.to_le_bytes())?;
        self.file.write_all(&header.mod_date.to_le_bytes())?;
        self.file.write_all(&header.crc32.to_le_bytes())?;
        self.file.write_all(&header.compressed_size.to_le_bytes())?;
        self.file
            .write_all(&header.uncompressed_size.to_le_bytes())?;
        self.file
            .write_all(&(header.filename.len() as u16).to_le_bytes())?;
        self.file
            .write_all(&(header.extra_field.len() as u16).to_le_bytes())?;
        self.file.write_all(&header.filename)?;
        self.file.write_all(&header.extra_field)?;
        Ok(())
    }

    // 辅助函数：写入中央目录头
    fn write_central_directory_header(
        &mut self,
        header: &CentralDirectoryHeader,
    ) -> anyhow::Result<()> {
        self.file.write_all(&[0x50, 0x4B, 0x01, 0x02])?; // 中央目录签名

        // 写入版本信息
        self.file.write_all(&header.version_made.to_le_bytes())?;
        self.file.write_all(&header.version_needed.to_le_bytes())?;

        // 写入标志和压缩方法
        self.file.write_all(&header.flags.to_le_bytes())?;
        self.file.write_all(&header.compression.to_le_bytes())?;

        // 写入修改时间和日期
        self.file.write_all(&header.mod_time.to_le_bytes())?;
        self.file.write_all(&header.mod_date.to_le_bytes())?;

        // 写入CRC和大小信息
        self.file.write_all(&header.crc32.to_le_bytes())?;
        self.file.write_all(&header.compressed_size.to_le_bytes())?;
        self.file
            .write_all(&header.uncompressed_size.to_le_bytes())?;

        // 写入文件名和额外字段长度
        self.file
            .write_all(&(header.filename.len() as u16).to_le_bytes())?;
        self.file
            .write_all(&(header.extra_field.len() as u16).to_le_bytes())?;
        self.file
            .write_all(&(header.file_comment.len() as u16).to_le_bytes())?;

        // 写入磁盘编号和文件属性
        self.file.write_all(&header.disk_num.to_le_bytes())?;
        self.file.write_all(&header.internal_attr.to_le_bytes())?;
        self.file.write_all(&header.external_attr.to_le_bytes())?;

        // 写入本地头偏移量
        self.file
            .write_all(&header.local_header_offset.to_le_bytes())?;

        // 写入文件名、额外字段和注释
        self.file.write_all(&header.filename)?;
        self.file.write_all(&header.extra_field)?;
        self.file.write_all(&header.file_comment)?;

        Ok(())
    }

    // 实现结束中央目录记录写入
    fn write_end_of_central_directory(&mut self) -> anyhow::Result<()> {
        self.file.write_all(&[0x50, 0x4B, 0x05, 0x06])?; // 结束记录签名

        // 写入磁盘信息
        let disk_num = if self.split_size.is_some() {
            self.current_split_index - 1_u16
        } else {
            0
        };

        // 写入磁盘信息
        self.file.write_all(&disk_num.to_le_bytes())?; // 当前磁盘编号
        self.file.write_all(&disk_num.to_le_bytes())?; // 中央目录开始磁盘
        self.file
            .write_all(&self.archive_info.num_entries.to_le_bytes())?; // 本磁盘记录数
        self.file
            .write_all(&self.archive_info.num_entries.to_le_bytes())?; // 总记录数

        // 写入中央目录大小和偏移
        self.file.write_all(&self.archive_info.size.to_le_bytes())?;
        self.file
            .write_all(&self.archive_info.offset.to_le_bytes())?;

        // 写入注释长度和内容
        self.file
            .write_all(&(self.archive_info.comment.len() as u16).to_le_bytes())?;
        self.file.write_all(self.archive_info.comment.as_bytes())?;

        Ok(())
    }

    // 获取注释
    pub fn get_archive_comment(&self) -> &String {
        &self.archive_info.comment
    }

    // 新增: 在写入过程中切换到下一个分卷
    fn switch_to_next_split(&mut self) -> anyhow::Result<()> {
        if self.split_bell {
            // 响铃提示
            print!("\x07");
            std::io::stdout().flush()?;
        }

        if self.current_split_index == 1 {
            // 第一次分卷需要将 .zip 重命名为 .z01
            let new_path = format!("{}.z{:02}", self.base_name, self.current_split_index);
            std::fs::rename(&self.output_path, &new_path)?;
            if self.split_verbose {
                println!("\n      Closing split {}", new_path);
            }
        } else if self.split_verbose {
            println!("      Closing split {}", self.output_path);
        }

        // 创建新分卷文件
        self.current_split_index += 1;
        let split_file_name = format!("{}.z{:02}", self.base_name, self.current_split_index);
        let mut new_path = if let Some(cb) = &mut self.split_callback {
            cb(self.current_split_index)?
        } else {
            PathBuf::from(".")
        };
        new_path = new_path.join(&split_file_name);

        self.file = File::create(&new_path)?;
        self.output_path = new_path.to_string_lossy().to_string();
        Ok(())
    }
}

// 新增 ZipFile 结构体
#[derive(Debug, Clone)]
pub struct ZipFile {
    header: CentralDirectoryHeader,
    #[allow(dead_code)]
    data_start: u64,
    data_end: u64,
    file: Arc<File>,
}

impl ZipFile {
    pub fn name(&self) -> String {
        String::from_utf8_lossy(&self.header.filename).to_string()
    }

    #[allow(dead_code)]
    pub fn extra_field(&self) -> &[u8] {
        &self.header.extra_field
    }

    #[allow(dead_code)]
    pub fn header(&self) -> &CentralDirectoryHeader {
        &self.header
    }
    #[allow(dead_code)]
    pub fn header_mut(&mut self) -> &mut CentralDirectoryHeader {
        &mut self.header
    }

    #[allow(dead_code)]
    pub fn comments(&self) -> String {
        String::from_utf8_lossy(&self.header.file_comment).to_string()
    }

    #[allow(dead_code)]
    pub fn set_comments(&mut self, comment: &str) {
        self.header.file_comment = comment.as_bytes().to_vec();
    }

    #[allow(dead_code)]
    pub fn options(&self) -> FileOptions {
        let mut file_options = FileOptions::new();
        file_options.compression_method = self.header.compression;
        file_options.password = None;
        file_options.compression_level = match self.header.compression {
            CompressionMethod::Stored => 0,
            CompressionMethod::Deflated => 6, // 默认压缩级别
            CompressionMethod::Bzip2 => 9,    // Bzip2默认压缩级别
        };
        file_options.modification_time = Some((self.header.mod_time, self.header.mod_date));
        file_options.external_attr = self.header.external_attr;
        file_options.extra_field = self.header.extra_field.clone();

        file_options.compress_size = self.header.compressed_size;
        file_options.uncompress_size = self.header.uncompressed_size as u64;
        file_options.crc32 = self.header.crc32;

        file_options
    }

    #[allow(dead_code)]
    pub fn is_dir(&self) -> bool {
        self.header.external_attr & 0x10 != 0
            || (!self.header.filename.is_empty() && *self.header.filename.last().unwrap() == b'/')
    }

    pub fn encrypted(&self) -> bool {
        self.header.flags & ZIP_CRYPTO_FLAG != 0
    }

    pub fn last_modified(&self) -> anyhow::Result<chrono::DateTime<Local>> {
        // 解析时间字段 (MS-DOS 时间格式)
        let time = self.header.mod_time;
        let hour = ((time >> 11) & 0x1F) as u32;
        let minute = ((time >> 5) & 0x3F) as u32;
        let second = (time & 0x1F) as u32 * 2; // MS-DOS 时间存储秒/2

        // 解析日期字段 (MS-DOS 日期格式)
        let date = self.header.mod_date;
        let day = (date & 0x1F) as u32;
        let month = ((date >> 5) & 0xF) as u32;
        let year = (date >> 9) as u32 + 1980; // MS-DOS 日期从1980年开始

        // 创建日期时间对象
        Local
            .with_ymd_and_hms(year as i32, month, day, hour, minute, second)
            .single()
            .ok_or_else(|| anyhow::anyhow!("Invalid date time in zip header"))
    }

    #[allow(dead_code)]
    pub fn compression(&self) -> CompressionMethod {
        self.header.compression
    }

    pub fn origin_size(&self) -> u64 {
        self.header.get_uncompressed_size()
    }

    pub fn compressed_size(&self) -> u64 {
        self.header.get_compressed_size()
    }

    #[allow(dead_code)]
    pub fn data_size(&self) -> u64 {
        self.data_end - self.header.get_local_header_offset()
    }

    pub fn compression_method(&self) -> CompressionMethod {
        self.header.compression
    }

    #[allow(dead_code)]
    pub fn crc32(&self) -> u32 {
        self.header.crc32
    }

    // 获取中央目录头的长度
    #[allow(dead_code)]
    pub fn get_center_header_len(&self) -> u32 {
        (self.header.filename.len()
            + self.header.extra_field.len()
            + self.header.file_comment.len()
            + CENTRAL_DIR_HEADER_SIZE) as u32 // 中央目录头的固定长度
    }
}

#[derive(Debug)]
pub struct ZipArchive {
    file: File,
    cd_headers: Vec<CentralDirectoryHeader>,
    arhive_info: ArchiveFileInfo,
    // 分割文件支持
    #[allow(dead_code)]
    split_files: Option<Vec<String>>, // 分割文件路径列表
    #[allow(dead_code)]
    base_name: Option<String>, // 基础文件名
}

impl ZipArchive {
    pub fn new(path: &str) -> anyhow::Result<Self> {
        // 首先检查是否是分割文件
        if Self::is_split_archive(path)? {
            Self::new_from_split(path)
        } else {
            Self::new_from_single_file(path)
        }
    }

    // 检查是否是分割文件
    fn is_split_archive(path: &str) -> anyhow::Result<bool> {
        let path_buf = std::path::Path::new(path);

        // 检查文件扩展名
        if let Some(extension) = path_buf.extension() {
            let ext = extension.to_string_lossy().to_lowercase();
            if ext.starts_with('z') && ext.len() == 3 {
                // 可能是 .z01, .z02 等
                return Ok(true);
            }
        }

        // 检查是否存在对应的分割文件
        let base_name = if let Some(stripped) = path.strip_suffix(".zip") {
            stripped
        } else {
            path
        };

        let first_split = format!("{}.z01", base_name);
        Ok(std::path::Path::new(&first_split).exists())
    }

    // 从分割文件创建ZipArchive
    fn new_from_split(path: &str) -> anyhow::Result<Self> {
        // 获取基础文件名
        let base_name = if let Some(stripped) = path.strip_suffix(".zip") {
            stripped
        } else if path.contains(".z") {
            // 处理 .z01, .z02 等格式
            let parts: Vec<&str> = path.rsplitn(2, ".z").collect();
            if parts.len() == 2 {
                parts[1]
            } else {
                return Err(anyhow::anyhow!("Invalid split archive name format"));
            }
        } else {
            path
        };

        // 查找所有分割文件
        let mut split_files = Vec::new();

        // 添加 .z01, .z02, ... 文件
        for i in 1..=999 {
            let split_path = format!("{}.z{:02}", base_name, i);
            if std::path::Path::new(&split_path).exists() {
                split_files.push(split_path);
            } else {
                break;
            }
        }

        // 添加最后的 .zip 文件
        let final_path = format!("{}.zip", base_name);
        if std::path::Path::new(&final_path).exists() {
            split_files.push(final_path);
        }

        if split_files.is_empty() {
            return Err(anyhow::anyhow!("No split files found for: {}", path));
        }

        log::debug!("Found {} split files", split_files.len());

        // 从最后一个文件（通常是.zip）读取中央目录
        let last_file_path = split_files.last().unwrap();
        let mut last_file = std::fs::OpenOptions::new()
            .read(true)
            .open(last_file_path)
            .with_context(|| format!("Failed to open last split file: {}", last_file_path))?;

        log::debug!("Reading archive info from: {}", last_file_path);
        let archive_info = Self::read_archive_info(&mut last_file)?;
        let cd_headers = Self::read_central_directory_headers(&mut last_file, &archive_info)?;

        // 创建一个虚拟的合并文件视图
        // 注意：这里我们使用最后一个文件作为主文件，但在实际读取数据时需要特殊处理
        Ok(Self {
            file: last_file,
            cd_headers,
            arhive_info: archive_info,
            split_files: Some(split_files),
            base_name: Some(base_name.to_string()),
        })
    }

    // 从单个文件创建ZipArchive（原有逻辑）
    fn new_from_single_file(path: &str) -> anyhow::Result<Self> {
        let mut file = std::fs::OpenOptions::new()
            .read(true)
            .write(true)
            .open(path)
            .with_context(|| format!("Failed to open existing zip file: {}", path))?;

        log::debug!("start read archive info...");
        let arhive_info = Self::read_archive_info(&mut file)?;
        log::debug!("archive info end");
        let cd_headers = Self::read_central_directory_headers(&mut file, &arhive_info)?;
        log::debug!("cd headers end");
        Ok(Self {
            file,
            cd_headers,
            arhive_info,
            split_files: None,
            base_name: None,
        })
    }

    #[allow(dead_code)]
    pub fn archive_info(&self) -> &ArchiveFileInfo {
        &self.arhive_info
    }

    #[allow(dead_code)]
    pub fn get_total_size(&self) -> u64 {
        self.file.metadata().unwrap().len()
    }

    pub fn get_total_original_size(&self) -> u64 {
        self.cd_headers
            .iter()
            .map(|header| header.uncompressed_size as u64)
            .sum()
    }
    pub fn get_total_compressed_size(&self) -> u64 {
        self.cd_headers
            .iter()
            .map(|header| header.compressed_size as u64)
            .sum()
    }

    // 读取ZIP文件头信息
    fn read_archive_info(file: &mut File) -> anyhow::Result<ArchiveFileInfo> {
        // 定位到文件末尾查找结束记录
        let file_size = file.metadata()?.len();
        log::debug!("File size: {}", file_size);

        // 首先检查文件是否足够小(小于最小ZIP文件大小)
        if file_size < 22 {
            // 最小ZIP文件(空文件)大小约为22字节
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                "File too small to be a valid ZIP file",
            )
            .into());
        }

        // 查找结束记录签名
        let end_record_pos = Self::find_end_record_signature(file.try_clone()?, file_size)?;

        // 读取结束记录
        file.seek(io::SeekFrom::Start(end_record_pos))?;
        let mut end_record = [0u8; 22];
        file.read_exact(&mut end_record)?;

        let cd_offset = u32::from_le_bytes([
            end_record[16],
            end_record[17],
            end_record[18],
            end_record[19],
        ]);
        let cd_size = u32::from_le_bytes([
            end_record[12],
            end_record[13],
            end_record[14],
            end_record[15],
        ]);
        let num_entries = u16::from_le_bytes([end_record[8], end_record[9]]);
        let comment_len = u16::from_le_bytes([end_record[20], end_record[21]]);

        let comment = if comment_len > 0 {
            let mut comment_buffer = vec![0u8; comment_len as usize];
            file.read_exact(&mut comment_buffer)?;
            String::from_utf8_lossy(&comment_buffer).to_string()
        } else {
            String::new()
        };

        let mut archive_info = ArchiveFileInfo {
            num_entries,
            size: cd_size,
            offset: cd_offset,
            comment,
            is_zip64: false,
            zip64_num_entries: None,
            zip64_size: None,
            zip64_offset: None,
        };

        // 检查是否存在ZIP64结构
        if num_entries == MAX_ZIP_ENTRIES || cd_size == MAX_ZIP_SIZE || cd_offset == MAX_ZIP_SIZE {
            // 可能是ZIP64格式，尝试查找ZIP64结束目录定位器
            if let Ok(zip64_info) = Self::read_zip64_info(file, end_record_pos) {
                archive_info.is_zip64 = true;
                archive_info.zip64_num_entries = Some(zip64_info.total_entries);
                archive_info.zip64_size = Some(zip64_info.central_dir_size);
                archive_info.zip64_offset = Some(zip64_info.central_dir_offset);
                log::debug!("Detected ZIP64 format");
            }
        }

        Ok(archive_info)
    }

    // 读取ZIP64信息
    fn read_zip64_info(
        file: &mut File,
        end_record_pos: u64,
    ) -> anyhow::Result<Zip64EndOfCentralDir> {
        // 检查ZIP64结束目录定位器
        if end_record_pos < ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE as u64 {
            return Err(anyhow::anyhow!("File too small for ZIP64 locator"));
        }

        let locator_pos = end_record_pos - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE as u64;
        file.seek(io::SeekFrom::Start(locator_pos))?;

        // 读取ZIP64结束目录定位器签名
        let mut signature = [0u8; 4];
        file.read_exact(&mut signature)?;
        if signature != [0x50, 0x4B, 0x06, 0x07] {
            return Err(anyhow::anyhow!("ZIP64 locator signature not found"));
        }

        // 读取定位器数据
        let mut locator_data = [0u8; 16];
        file.read_exact(&mut locator_data)?;

        let _central_dir_disk = u32::from_le_bytes([
            locator_data[0],
            locator_data[1],
            locator_data[2],
            locator_data[3],
        ]);
        let zip64_end_offset = u64::from_le_bytes([
            locator_data[4],
            locator_data[5],
            locator_data[6],
            locator_data[7],
            locator_data[8],
            locator_data[9],
            locator_data[10],
            locator_data[11],
        ]);
        let _total_disks = u32::from_le_bytes([
            locator_data[12],
            locator_data[13],
            locator_data[14],
            locator_data[15],
        ]);

        // 读取ZIP64结束目录记录
        file.seek(io::SeekFrom::Start(zip64_end_offset))?;

        // 读取ZIP64结束目录记录签名
        file.read_exact(&mut signature)?;
        if signature != [0x50, 0x4B, 0x06, 0x06] {
            return Err(anyhow::anyhow!("ZIP64 end record signature not found"));
        }

        // 读取ZIP64结束目录记录
        let mut record_data = [0u8; 52]; // 不包括签名的记录大小
        file.read_exact(&mut record_data)?;

        let size_of_record = u64::from_le_bytes([
            record_data[0],
            record_data[1],
            record_data[2],
            record_data[3],
            record_data[4],
            record_data[5],
            record_data[6],
            record_data[7],
        ]);
        let version_made = u16::from_le_bytes([record_data[8], record_data[9]]);
        let version_needed = u16::from_le_bytes([record_data[10], record_data[11]]);
        let disk_number = u32::from_le_bytes([
            record_data[12],
            record_data[13],
            record_data[14],
            record_data[15],
        ]);
        let central_dir_disk_num = u32::from_le_bytes([
            record_data[16],
            record_data[17],
            record_data[18],
            record_data[19],
        ]);
        let entries_on_disk = u64::from_le_bytes([
            record_data[20],
            record_data[21],
            record_data[22],
            record_data[23],
            record_data[24],
            record_data[25],
            record_data[26],
            record_data[27],
        ]);
        let total_entries = u64::from_le_bytes([
            record_data[28],
            record_data[29],
            record_data[30],
            record_data[31],
            record_data[32],
            record_data[33],
            record_data[34],
            record_data[35],
        ]);
        let central_dir_size = u64::from_le_bytes([
            record_data[36],
            record_data[37],
            record_data[38],
            record_data[39],
            record_data[40],
            record_data[41],
            record_data[42],
            record_data[43],
        ]);
        let central_dir_offset = u64::from_le_bytes([
            record_data[44],
            record_data[45],
            record_data[46],
            record_data[47],
            record_data[48],
            record_data[49],
            record_data[50],
            record_data[51],
        ]);

        Ok(Zip64EndOfCentralDir {
            size_of_record,
            version_made,
            version_needed,
            disk_number,
            central_dir_disk: central_dir_disk_num,
            entries_on_disk,
            total_entries,
            central_dir_size,
            central_dir_offset,
        })
    }

    // 查找结束记录签名位置
    pub fn find_end_record_signature(mut file: File, file_size: u64) -> anyhow::Result<u64> {
        log::debug!("start find end record signature...");

        // 从文件末尾开始查找，最多向前查找1MB或整个文件大小
        let max_search_size = std::cmp::min(1024 * 1024, file_size);
        let mut pos = file_size.saturating_sub(max_search_size);

        // 读取缓冲区大小设置为4KB
        const BUF_SIZE: usize = 4096;
        let mut buffer = [0u8; BUF_SIZE];

        while pos + 4 < file_size {
            // 计算当前读取位置和大小
            let read_pos = pos;
            let read_size = std::cmp::min(BUF_SIZE as u64, file_size - read_pos) as usize;

            // 读取数据块
            file.seek(io::SeekFrom::Start(read_pos))?;
            file.read_exact(&mut buffer[..read_size])?;

            // 在缓冲区中查找签名
            for i in 0..read_size.saturating_sub(3) {
                if buffer[i] == 0x50
                    && buffer[i + 1] == 0x4B
                    && buffer[i + 2] == 0x05
                    && buffer[i + 3] == 0x06
                {
                    let found_pos = read_pos + i as u64;
                    log::debug!("end find end record signature at {}", found_pos);
                    return Ok(found_pos);
                }
            }

            pos += read_size as u64;
        }

        Err(anyhow::anyhow!("not found end record signature"))
    }
    // 读取中央目录头
    fn read_central_directory_headers(
        file: &mut File,
        arhive_info: &ArchiveFileInfo,
    ) -> anyhow::Result<Vec<CentralDirectoryHeader>> {
        // 使用ZIP64信息（如果可用）
        let cd_offset = arhive_info.get_offset();
        let num_entries = arhive_info.get_num_entries();

        // 读取中央目录
        file.seek(io::SeekFrom::Start(cd_offset))?;
        let mut cd_headers = Vec::with_capacity(num_entries as usize);

        for _ in 0..num_entries {
            let mut signature = [0u8; 4];
            file.read_exact(&mut signature)?;
            if signature != [0x50, 0x4B, 0x01, 0x02] {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidData,
                    "Invalid central directory signature",
                )
                .into());
            }

            // 读取固定长度的头部字段
            let mut header_bytes = [0u8; 42];
            file.read_exact(&mut header_bytes)?;

            let version_made = u16::from_le_bytes([header_bytes[0], header_bytes[1]]);
            let version_needed = u16::from_le_bytes([header_bytes[2], header_bytes[3]]);
            let flags = u16::from_le_bytes([header_bytes[4], header_bytes[5]]);
            let compression = u16::from_le_bytes([header_bytes[6], header_bytes[7]]);
            let mod_time = u16::from_le_bytes([header_bytes[8], header_bytes[9]]);
            let mod_date = u16::from_le_bytes([header_bytes[10], header_bytes[11]]);
            let crc32 = u32::from_le_bytes([
                header_bytes[12],
                header_bytes[13],
                header_bytes[14],
                header_bytes[15],
            ]);
            let compressed_size = u32::from_le_bytes([
                header_bytes[16],
                header_bytes[17],
                header_bytes[18],
                header_bytes[19],
            ]);
            let uncompressed_size = u32::from_le_bytes([
                header_bytes[20],
                header_bytes[21],
                header_bytes[22],
                header_bytes[23],
            ]);
            let filename_len = u16::from_le_bytes([header_bytes[24], header_bytes[25]]);
            let extra_field_len = u16::from_le_bytes([header_bytes[26], header_bytes[27]]);
            let file_comment_len = u16::from_le_bytes([header_bytes[28], header_bytes[29]]);
            let disk_num = u16::from_le_bytes([header_bytes[30], header_bytes[31]]);
            let internal_attr = u16::from_le_bytes([header_bytes[32], header_bytes[33]]);
            let external_attr = u32::from_le_bytes([
                header_bytes[34],
                header_bytes[35],
                header_bytes[36],
                header_bytes[37],
            ]);
            let local_header_offset = u32::from_le_bytes([
                header_bytes[38],
                header_bytes[39],
                header_bytes[40],
                header_bytes[41],
            ]);

            // 读取文件名、额外字段和注释
            let mut filename = vec![0u8; filename_len as usize];
            file.read_exact(&mut filename)?;

            let mut extra_field = vec![0u8; extra_field_len as usize];
            file.read_exact(&mut extra_field)?;

            let mut file_comment = vec![0u8; file_comment_len as usize];
            file.read_exact(&mut file_comment)?;

            let mut header = CentralDirectoryHeader {
                version_made,
                version_needed,
                flags,
                compression: CompressionMethod::from(compression),
                mod_time,
                mod_date,
                crc32,
                compressed_size,
                uncompressed_size,
                filename,
                extra_field,
                file_comment,
                disk_num,
                internal_attr,
                external_attr,
                local_header_offset,
                zip64_extended_info: None,
            };

            // 解析ZIP64扩展字段（如果存在）
            header.parse_zip64_extra_field()?;

            cd_headers.push(header);
        }

        if cd_headers.is_empty() {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                "No central directory headers found",
            )
            .into());
        }
        Ok(cd_headers)
    }

    pub fn files(&self) -> impl Iterator<Item = ZipFile> + '_ {
        self.cd_headers
            .iter()
            .filter_map(|header| self.get_zip_file(header).ok())
    }

    pub fn file_names(&self) -> Vec<String> {
        self.cd_headers
            .iter()
            .map(|header| String::from_utf8_lossy(&header.filename).to_string())
            .collect()
    }

    #[allow(clippy::len_without_is_empty)]
    pub fn len(&self) -> usize {
        self.cd_headers.len()
    }

    pub fn by_name(&mut self, name: &str) -> anyhow::Result<ZipFile> {
        let display_name = name.trim_start_matches('/');
        let name_bytes = display_name.as_bytes();
        for i in 0..self.cd_headers.len() {
            if self.cd_headers[i].filename == name_bytes {
                return self.by_index_raw(i);
            }
        }
        Err(anyhow::anyhow!("File not found: {}", name))
    }

    pub fn by_index_raw(&self, index: usize) -> anyhow::Result<ZipFile> {
        if index >= self.cd_headers.len() {
            return Err(anyhow::anyhow!("索引超出范围"));
        }

        self.get_zip_file(&self.cd_headers[index])
    }

    // 统一文件读取逻辑
    #[allow(dead_code)]
    pub fn read_file(&self, zip_file: &ZipFile, password: Option<&str>) -> anyhow::Result<Vec<u8>> {
        let (data_start, compressed_size) =
            self.locate_and_validate_file_data(zip_file, password.is_some())?;

        let mut data = vec![0u8; compressed_size as usize];
        (&self.file).seek(io::SeekFrom::Start(data_start))?;
        (&self.file).read_exact(&mut data)?;

        if let Some(pwd) = password {
            // 如果有密码，解密数据
            let mut decrypt = ZipCryptoDecryptor::new(pwd, zip_file.header.crc32);
            data = decrypt.decrypt_chunk(&data)?;
        }

        self.decompress_data(
            &data[..],
            zip_file.header.compression,
            zip_file.header.get_uncompressed_size(),
            zip_file.header.crc32,
        )
    }

    // 新增方法获取完整的ZipFile对象
    fn get_zip_file(&self, header: &CentralDirectoryHeader) -> anyhow::Result<ZipFile> {
        // 使用ZIP64信息（如果可用）
        let local_header_offset = header.get_local_header_offset();
        let compressed_size = header.get_compressed_size();

        // 读取整个条目数据(包括本地文件头和数据)
        // 30 = 本地文件头固定部分大小(签名4 + 版本2 + 标志2 + 压缩方法2 + 时间2 + 日期2 + CRC4 + 压缩大小4 + 未压缩大小4 + 文件名长度2 + 额外字段长度2)
        let local_header_size = 30 + header.filename.len() as u64 + header.extra_field.len() as u64;

        let total_size = local_header_size + compressed_size;

        Ok(ZipFile {
            header: header.clone(),
            data_start: local_header_offset + local_header_size,
            data_end: local_header_offset + total_size,
            file: self.file.try_clone()?.into(),
        })
    }

    // 获取ZIP文件原始数据(不包含文件头)
    #[allow(dead_code)]
    pub fn get_raw_file_data(
        &self,
        entry: &ZipFile,
        password: Option<&str>,
    ) -> anyhow::Result<Vec<u8>> {
        // 使用新的分割文件读取方法
        let data = self.read_split_data(entry.data_start, entry.header.get_compressed_size())?;

        if let Some(pwd) = password {
            let mut decrypt = ZipCryptoDecryptor::new(pwd, entry.header.crc32);
            let decrypted_data = decrypt.decrypt_chunk(&data)?;
            Ok(decrypted_data)
        } else {
            Ok(data)
        }
    }

    #[allow(dead_code)]
    fn decompress_data(
        &self,
        data: &[u8],
        method: CompressionMethod,
        expected_size: u64,
        expected_crc: u32,
    ) -> anyhow::Result<Vec<u8>> {
        match method {
            CompressionMethod::Stored => Ok(data.to_vec()),
            CompressionMethod::Deflated => {
                let mut decoder = flate2::read::DeflateDecoder::new(data);
                let mut result = Vec::with_capacity(expected_size as usize);
                decoder.read_to_end(&mut result)?;
                self.validate_decompressed_data(&result, expected_size, expected_crc)?;
                Ok(result)
            }
            CompressionMethod::Bzip2 => {
                let mut decoder = bzip2::read::BzDecoder::new(data);
                let mut result = Vec::with_capacity(expected_size as usize);
                decoder.read_to_end(&mut result)?;

                self.validate_decompressed_data(&result, expected_size, expected_crc)?;
                Ok(result)
            }
        }
    }

    // 验证解压缩后的数据
    #[allow(dead_code)]
    fn validate_decompressed_data(
        &self,
        result: &[u8],
        expected_size: u64,
        expected_crc: u32,
    ) -> anyhow::Result<()> {
        // 验证大小
        if result.len() != expected_size as usize {
            return Err(anyhow::anyhow!(
                "大小不匹配: 预期 {} 字节, 实际 {} 字节",
                expected_size,
                result.len()
            ));
        }

        // 验证 CRC32
        let mut hasher = Hasher::new();
        hasher.update(result);
        if hasher.finalize() != expected_crc {
            return Err(anyhow::anyhow!("CRC32校验失败"));
        }

        Ok(())
    }

    // 提取公共的文件头验证和定位逻辑
    #[allow(dead_code)]
    fn locate_and_validate_file_data(
        &self,
        zip_file: &ZipFile,
        is_encrypted: bool,
    ) -> anyhow::Result<(u64, u64)> {
        let mut file = &self.file;

        file.seek(io::SeekFrom::Start(
            zip_file.header.get_local_header_offset(),
        ))?;

        // 验证文件头签名
        let mut signature = [0u8; 4];
        file.read_exact(&mut signature)?;
        if signature != [0x50, 0x4B, 0x03, 0x04] {
            return Err(anyhow::Error::from(io::Error::new(
                io::ErrorKind::InvalidData,
                "Invalid local file header signature",
            )));
        }

        // 读取并验证压缩大小
        let mut header = [0u8; 22];
        file.read_exact(&mut header)?;
        let local_compressed_size =
            u32::from_le_bytes([header[14], header[15], header[16], header[17]]) as u64;

        // 对于ZIP64文件或加密文件，跳过压缩大小验证
        let needs_validation = !is_encrypted && !zip_file.header.needs_zip64();
        if needs_validation && local_compressed_size != zip_file.header.get_compressed_size() {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    "压缩大小不一致: 中央目录记录 {}, 本地文件头 {}",
                    zip_file.header.get_compressed_size(),
                    local_compressed_size
                ),
            )
            .into());
        }

        // 读取文件名和额外字段长度
        let mut len_bytes = [0u8; 4];
        file.read_exact(&mut len_bytes)?;
        let filename_len = u16::from_le_bytes([len_bytes[0], len_bytes[1]]) as u64;
        let extra_field_len = u16::from_le_bytes([len_bytes[2], len_bytes[3]]) as u64;

        // 计算并验证数据位置
        let data_start = file.stream_position()? + filename_len + extra_field_len;
        let file_size = file.metadata()?.len();

        // 确保压缩大小不超过文件剩余部分
        let expected_compressed_size = zip_file.header.get_compressed_size();
        let actual_compressed_size =
            std::cmp::min(expected_compressed_size, file_size - data_start);

        if actual_compressed_size == 0 {
            return Err(anyhow::Error::from(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    "无效的压缩大小: 需要读取 {} 字节 (从位置 {} 开始)，但文件大小只有 {} 字节",
                    expected_compressed_size, data_start, file_size
                ),
            )));
        }

        // 跳过文件名和额外字段
        file.seek(io::SeekFrom::Current(
            filename_len as i64 + extra_field_len as i64,
        ))?;

        Ok((data_start, actual_compressed_size))
    }

    // 获取文档的注释
    pub fn comment(&self) -> &str {
        &self.arhive_info.comment
    }

    /// 检查中央目录条目和本地文件头是否一致
    pub fn validate_local_header(
        file: &mut File,
        header: &CentralDirectoryHeader,
    ) -> anyhow::Result<()> {
        use std::io::{Read, Seek, SeekFrom};

        // 保存当前位置以便恢复
        let original_pos = file.stream_position()?;

        // 定位到本地文件头
        file.seek(SeekFrom::Start(header.get_local_header_offset()))?;

        // 读取本地文件头签名
        let mut sig = [0u8; 4];
        file.read_exact(&mut sig)?;
        if sig != [0x50, 0x4B, 0x03, 0x04] {
            return Err(anyhow::anyhow!("Signature mismatch"));
        }

        // 读取本地文件头剩余字段
        let mut buf: [u8; 26] = [0u8; 26];
        file.read_exact(&mut buf)?;

        let compression = u16::from_le_bytes([buf[4], buf[5]]);
        let crc32 = u32::from_le_bytes([buf[10], buf[11], buf[12], buf[13]]);
        let compressed_size = u32::from_le_bytes([buf[14], buf[15], buf[16], buf[17]]);
        let uncompressed_size = u32::from_le_bytes([buf[18], buf[19], buf[20], buf[21]]);
        let filename_len = u16::from_le_bytes([buf[22], buf[23]]) as usize;

        // 读取文件名和额外字段
        let mut filename = vec![0u8; filename_len];
        file.read_exact(&mut filename)?;

        if filename != header.filename {
            return Err(anyhow::anyhow!(
                "File name mismatch: local header {:?}, central directory {:?}",
                String::from_utf8(filename),
                String::from_utf8(header.filename.clone())
            ));
        }

        // 比较关键字段并返回具体错误信息
        if compression != (header.compression as u16) {
            return Err(anyhow::anyhow!(
                "Compression method mismatch: local header {}, central directory {}",
                compression,
                header.compression as u16
            ));
        }
        if crc32 != header.crc32 {
            return Err(anyhow::anyhow!(
                "CRC32 mismatch: local header {}, central directory {}",
                crc32,
                header.crc32
            ));
        }
        // 对于ZIP64文件，跳过大小验证（因为本地头可能显示最大值）
        if !header.needs_zip64() {
            if compressed_size != header.compressed_size {
                return Err(anyhow::anyhow!(
                    "Compressed size mismatch: local header {}, central directory {}",
                    compressed_size,
                    header.compressed_size
                ));
            }
            if uncompressed_size != header.uncompressed_size {
                return Err(anyhow::anyhow!(
                    "Uncompressed size mismatch: local header {}, central directory {}",
                    uncompressed_size,
                    header.uncompressed_size
                ));
            }
        }
        if filename != header.filename {
            return Err(anyhow::anyhow!(
                "Filename mismatch: local header {:?}, central directory {:?}",
                String::from_utf8(filename),
                String::from_utf8(header.filename.clone())
            ));
        }

        // 恢复文件指针
        file.seek(SeekFrom::Start(original_pos))?;

        Ok(())
    }

    // 加密条目数量
    #[allow(dead_code)]
    pub fn encrypted_entries_count(&self) -> usize {
        self.cd_headers
            .iter()
            .filter(|header| header.flags & 0x01 != 0)
            .count()
    }

    // 从分割文件中读取数据
    #[allow(dead_code)]
    fn read_split_data(&self, offset: u64, length: u64) -> anyhow::Result<Vec<u8>> {
        if let Some(split_files) = &self.split_files {
            let mut result = Vec::new();
            let mut remaining = length;
            let current_offset = offset;

            // 计算每个分割文件的大小（除了最后一个）
            let mut split_sizes = Vec::new();
            for split_path in split_files.iter() {
                let metadata = std::fs::metadata(split_path)
                    .with_context(|| format!("Failed to get metadata for: {}", split_path))?;
                split_sizes.push(metadata.len());
            }

            // 找到起始分割文件
            let mut cumulative_size = 0u64;
            let mut start_split_index = 0;
            let mut offset_in_split = current_offset;

            for (i, &size) in split_sizes.iter().enumerate() {
                if current_offset < cumulative_size + size {
                    start_split_index = i;
                    offset_in_split = current_offset - cumulative_size;
                    break;
                }
                cumulative_size += size;
            }

            // 从起始分割文件开始读取
            for split_index in start_split_index..split_files.len() {
                if remaining == 0 {
                    break;
                }

                let split_path = &split_files[split_index];
                let mut split_file = std::fs::File::open(split_path)
                    .with_context(|| format!("Failed to open split file: {}", split_path))?;

                // 定位到正确的偏移量
                split_file.seek(io::SeekFrom::Start(offset_in_split))?;

                // 计算在这个分割文件中要读取的字节数
                let available_in_split = split_sizes[split_index] - offset_in_split;
                let to_read = std::cmp::min(remaining, available_in_split);

                // 读取数据
                let mut buffer = vec![0u8; to_read as usize];
                split_file.read_exact(&mut buffer)?;
                result.extend_from_slice(&buffer);

                remaining -= to_read;
                offset_in_split = 0; // 后续分割文件从开头开始读取
            }

            if remaining > 0 {
                return Err(anyhow::anyhow!(
                    "Could not read all requested data from split files"
                ));
            }

            Ok(result)
        } else {
            // 单文件模式，使用原有逻辑
            let mut file = self.file.try_clone()?;
            file.seek(io::SeekFrom::Start(offset))?;
            let mut buffer = vec![0u8; length as usize];
            file.read_exact(&mut buffer)?;
            Ok(buffer)
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use tempfile::NamedTempFile;

    #[test]
    fn test_file_options() {
        let options1 = FileOptions::new();
        assert!(matches!(
            options1.compression_method,
            CompressionMethod::Deflated
        ));
        assert!(options1.password.is_none());

        let mut options = FileOptions::new();
        options.with_password("test");
        options.with_compression(CompressionMethod::Stored);
        assert!(matches!(
            options.compression_method,
            CompressionMethod::Stored
        ));
        assert_eq!(options.password.unwrap(), "test");
    }

    #[test]
    fn test_zip_writer_basic() -> anyhow::Result<()> {
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        let mut writer = ZipWriter::new(path)?;

        // Test adding a file
        writer.start_file("test.txt", FileOptions::new())?;
        writer.write_all(b"Hello World")?;
        writer.finish_file()?;

        // Test adding a directory
        let mut options = FileOptions::new();
        options.with_compression(CompressionMethod::Stored);
        writer.add_directory("test_dir/".to_string(), options)?;

        writer.finish()?;

        // Verify the archive
        let mut archive = ZipArchive::new(path)?;
        let files: Vec<_> = archive.files().collect();
        assert_eq!(files.len(), 2);

        let test_file = archive.by_name("test.txt")?;
        assert!(!test_file.is_dir());
        assert_eq!(test_file.origin_size(), 11);

        let test_dir = archive.by_name("test_dir/")?;
        assert!(test_dir.is_dir());

        Ok(())
    }

    #[test]
    fn test_zip_writer_encrypted() -> anyhow::Result<()> {
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        {
            let mut writer = ZipWriter::new(path)?;

            // Add encrypted file
            let mut options = FileOptions::new();
            options.with_password("secret");
            let secret_data = b"Top Secret";
            let mut hasher = Hasher::new();
            hasher.update(secret_data);
            options.crc32 = hasher.finalize();

            writer.start_file("secret.txt", options)?;
            writer.write_all(secret_data)?;
            writer.finish()?;
        }

        // Verify encryption
        let mut archive = ZipArchive::new(path)?;
        let secret_file = archive.by_name("secret.txt")?;
        assert!(secret_file.encrypted());

        // Test decryption
        let decrypted = archive.read_file(&secret_file, Some("secret"))?;
        assert_eq!(decrypted, b"Top Secret");

        // Test wrong password
        assert!(archive.read_file(&secret_file, Some("wrong")).is_err());

        Ok(())
    }

    #[test]
    fn test_zip_writer_compression() -> anyhow::Result<()> {
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        let mut writer = ZipWriter::new(path)?;

        // Add compressed file
        let mut options = FileOptions::new();
        options.with_compression(CompressionMethod::Deflated);

        writer.start_file("compressed.txt", options)?;
        writer.write_all(b"Some repeated text... Some repeated text... Some repeated text...")?;
        writer.finish_file()?;

        // Add uncompressed file
        let mut options = FileOptions::new();
        options.with_compression(CompressionMethod::Stored);

        writer.start_file("store.txt", options)?;
        writer.write_all(b"Small text")?;
        writer.finish_file()?;

        writer.finish()?;

        // Verify compression
        let mut archive = ZipArchive::new(path)?;
        let compressed = archive.by_name("compressed.txt")?;
        let stored = archive.by_name("store.txt")?;
        assert!(compressed.compressed_size() < compressed.origin_size());
        assert_eq!(stored.compressed_size(), stored.origin_size());

        Ok(())
    }

    #[test]
    fn test_auto_switch_to_store_mode() -> anyhow::Result<()> {
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        let mut writer = ZipWriter::new(path)?;

        // 添加一个小的不可压缩文件（随机数据）
        let random_data = (0..1000u32)
            .map(|i| ((i * 37) % 256) as u8)
            .collect::<Vec<u8>>();

        let mut options = FileOptions::new();
        options.with_compression(CompressionMethod::Deflated);
        // 不指定压缩级别，允许自动切换

        writer.start_file("random.bin", options)?;
        writer.write_all(&random_data)?;
        let _info = writer.finish_file()?;

        writer.finish()?;

        // 验证文件被自动切换到Store模式
        let mut archive = ZipArchive::new(path)?;
        let file = archive.by_name("random.bin")?;

        // 对于不可压缩的数据，应该自动切换到Store模式
        println!("Compression method: {:?}", file.compression_method());
        println!(
            "Original size: {}, Compressed size: {}",
            file.origin_size(),
            file.compressed_size()
        );

        // 验证数据完整性
        let content = archive.read_file(&file, None)?;
        assert_eq!(content, random_data);

        Ok(())
    }

    #[test]
    fn test_large_file_no_auto_switch() -> anyhow::Result<()> {
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        let mut writer = ZipWriter::new(path)?;

        // 创建一个大于32KB的不可压缩文件
        let large_random_data = (0..40000u32)
            .map(|i| ((i * 37) % 256) as u8)
            .collect::<Vec<u8>>();

        let mut options = FileOptions::new();
        options.with_compression(CompressionMethod::Deflated);

        writer.start_file("large_random.bin", options)?;
        writer.write_all(&large_random_data)?;
        writer.finish_file()?;

        writer.finish()?;

        // 验证大文件不会自动切换（因为超过32KB缓冲区限制）
        let mut archive = ZipArchive::new(path)?;
        let file = archive.by_name("large_random.bin")?;

        println!(
            "Large file - Compression method: {:?}",
            file.compression_method()
        );
        println!(
            "Large file - Original size: {}, Compressed size: {}",
            file.origin_size(),
            file.compressed_size()
        );

        // 验证数据完整性
        let content = archive.read_file(&file, None)?;
        assert_eq!(content, large_random_data);

        Ok(())
    }

    #[test]
    fn test_zip_writer_multiple_files() -> anyhow::Result<()> {
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        let mut writer = ZipWriter::new(path)?;

        // Add multiple files
        for i in 0..5 {
            let name = format!("file{}.txt", i);
            writer.start_file(&name, FileOptions::new())?;
            writer.write_all(format!("Content {}", i).as_bytes())?;
            writer.finish_file()?;
        }

        writer.finish()?;

        // Verify all files
        let archive = ZipArchive::new(path)?;
        let files: Vec<_> = archive.files().collect();
        assert_eq!(files.len(), 5);

        for (i, file) in files.iter().enumerate() {
            let expected_name = format!("file{}.txt", i);
            assert_eq!(file.name(), expected_name);
        }

        Ok(())
    }

    #[test]
    fn test_zip_writer_edge_cases() -> anyhow::Result<()> {
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        let mut writer = ZipWriter::new(path)?;

        // Empty file
        writer.start_file("empty.txt", FileOptions::new())?;
        writer.finish_file()?;

        // Large file
        let large_data = vec![0u8; 1024 * 1024]; // 1MB
        writer.start_file("large.bin", FileOptions::new())?;
        writer.write_all(&large_data)?;
        writer.finish_file()?;

        writer.finish()?;

        // Verify
        let mut archive = ZipArchive::new(path)?;
        let empty = archive.by_name("empty.txt")?;
        assert_eq!(empty.origin_size(), 0);

        let large = archive.by_name("large.bin")?;
        assert_eq!(large.origin_size(), 1024 * 1024);

        Ok(())
    }

    #[test]
    fn test_zip_archive_validation() {
        // Test invalid zip file
        let invalid_file = NamedTempFile::new().unwrap();
        assert!(ZipArchive::new(invalid_file.path().to_str().unwrap()).is_err());
    }

    #[test]
    fn test_zip_file_methods() -> anyhow::Result<()> {
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        let mut writer = ZipWriter::new(path)?;
        let mut options = FileOptions::new();
        options.with_compression(CompressionMethod::Deflated);
        writer.add_directory("test/".to_string(), options)?;
        writer.start_file("test.txt", FileOptions::new())?;
        writer.write_all(b"testtesttesttesttesttesttesttesttest")?;
        writer.finish_file()?;
        writer.finish()?;

        let mut archive = ZipArchive::new(path)?;
        let dir = archive.by_name("test/")?;
        let file = archive.by_name("test.txt")?;

        assert!(dir.is_dir());
        assert!(!file.is_dir());
        assert_eq!(file.name(), "test.txt");
        assert_eq!(file.origin_size(), 36);
        assert_eq!(file.compression_method(), CompressionMethod::Deflated);

        Ok(())
    }

    #[test]
    fn test_bzip2_compression() -> anyhow::Result<()> {
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        // 创建测试数据
        let test_data = "Test data ".repeat(100); // 创建重复的测试数据以便更好地压缩

        // 写入文件
        {
            let mut writer = ZipWriter::new(path)?;
            let mut options = FileOptions::new();
            options.with_compression(CompressionMethod::Bzip2);

            writer.start_file("test.txt", options)?;
            writer.write_all(test_data.as_bytes())?;
            writer.finish()?;
        }

        // 读取并验证
        {
            let mut archive = ZipArchive::new(path)?;
            let file = archive.by_name("test.txt")?;

            // 验证使用了 Bzip2 压缩
            assert_eq!(file.compression_method(), CompressionMethod::Bzip2);

            // 解压并验证内容
            let contents = archive.read_file(&file, None)?;
            assert_eq!(contents, test_data.as_bytes());

            // 验证压缩是否有效
            assert!(file.compressed_size() < file.origin_size());
        }

        Ok(())
    }

    #[test]
    fn test_copy_file_raw() -> anyhow::Result<()> {
        // 创建源文件
        let source_temp = NamedTempFile::new()?;
        let source_path = source_temp.path().to_str().unwrap();

        // 创建目标文件
        let target_temp = NamedTempFile::new()?;
        let target_path = target_temp.path().to_str().unwrap();

        // 1. 准备源文件
        {
            let mut writer = ZipWriter::new(source_path)?;

            // 添加普通文件
            let mut normal_options = FileOptions::new();
            let normal_data = b"Hello World";
            let mut hasher = Hasher::new();
            hasher.update(normal_data);
            normal_options.crc32 = hasher.finalize();
            writer.start_file("normal.txt", normal_options)?;
            writer.write_all(normal_data)?;
            writer.finish_file()?;

            // 添加加密文件
            let mut encrypted_options = FileOptions::new();
            encrypted_options.with_password("secret");
            let secret_data = b"Top Secret";
            let mut hasher = Hasher::new();
            hasher.update(secret_data);
            encrypted_options.crc32 = hasher.finalize();
            writer.start_file("secret.txt", encrypted_options)?;
            writer.write_all(secret_data)?;
            writer.finish_file()?;

            // 添加压缩文件
            let mut compressed_options = FileOptions::new();
            compressed_options.with_compression(CompressionMethod::Deflated);
            compressed_options.with_compression_level(9);
            let compressed_data = b"Compress me! Compress me! Compress me!";
            let mut hasher = Hasher::new();
            hasher.update(compressed_data);
            compressed_options.crc32 = hasher.finalize();
            writer.start_file("compressed.txt", compressed_options)?;
            writer.write_all(compressed_data)?;
            writer.finish_file()?;

            writer.finish()?;
        }

        // 2. 执行文件拷贝
        {
            let mut source_archive = ZipArchive::new(source_path)?;
            let mut target_writer = ZipWriter::new(target_path)?;

            // 拷贝普通文件
            let normal_file = source_archive.by_name("normal.txt")?;
            target_writer.raw_copy_file(&normal_file, "new_normal.txt".to_string())?;

            // 拷贝加密文件(保持原名)
            let secret_file = source_archive.by_name("secret.txt")?;
            target_writer.raw_copy_file(&secret_file, "".to_string())?;

            // 拷贝压缩文件
            let compressed_file = source_archive.by_name("compressed.txt")?;
            target_writer.raw_copy_file(&compressed_file, "".to_string())?;

            target_writer.finish()?;
        }

        // 3. 验证拷贝结果
        {
            let mut target_archive = ZipArchive::new(target_path)?;

            // 验证普通文件
            let new_normal = target_archive.by_name("new_normal.txt")?;
            assert_eq!(target_archive.read_file(&new_normal, None)?, b"Hello World");

            // 验证加密文件
            let new_secret = target_archive.by_name("secret.txt")?;
            assert!(new_secret.encrypted());
            assert_eq!(
                target_archive.read_file(&new_secret, Some("secret"))?,
                b"Top Secret"
            );

            // 验证压缩文件
            let new_compressed = target_archive.by_name("compressed.txt")?;
            assert_eq!(
                new_compressed.compression_method(),
                CompressionMethod::Deflated
            );
            assert!(new_compressed.compressed_size() < new_compressed.origin_size());
            assert_eq!(
                target_archive.read_file(&new_compressed, None)?,
                b"Compress me! Compress me! Compress me!"
            );

            // 验证文件总数
            let files: Vec<_> = target_archive.files().collect();
            assert_eq!(files.len(), 3);
        }

        Ok(())
    }

    #[test]
    fn test_read_central_directory() -> anyhow::Result<()> {
        // 1. 准备测试文件
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        let mut writer = ZipWriter::new(path)?;

        // 添加多个不同类型的文件
        // 1. 普通文件
        writer.start_file("normal.txt", FileOptions::new())?;
        writer.write_all(b"Hello World Hello World Hello World")?;
        writer.finish_file()?;

        // 2. 加密文件
        let mut encrypted_options = FileOptions::new();
        encrypted_options.with_password("secret");
        writer.start_file("secret.txt", encrypted_options)?;
        writer.write_all(b"Top Secret Top Secret Top Secret")?;
        writer.finish_file()?;

        // 3. 压缩文件
        let mut compressed_options = FileOptions::new();
        compressed_options.with_compression(CompressionMethod::Deflated);
        writer.start_file("compressed.txt", compressed_options)?;
        writer.write_all(b"Compress this content Compress this content")?;
        writer.finish_file()?;

        // 4. 目录
        let mut dir_options = FileOptions::new();
        dir_options.with_compression(CompressionMethod::Stored);
        writer.add_directory("test_dir/".to_string(), dir_options)?;

        writer.finish()?;

        // 2. 读取并验证中央目录
        let mut file = File::open(path)?;
        let archive_info = ZipArchive::read_archive_info(&mut file)?;
        let cd_headers = ZipArchive::read_central_directory_headers(&mut file, &archive_info)?;

        // 验证中央目录条目数量
        assert_eq!(cd_headers.len(), 4);

        // 验证各个条目的属性
        let normal_header = cd_headers
            .iter()
            .find(|h| String::from_utf8_lossy(&h.filename) == "normal.txt")
            .expect("未找到普通文件");
        assert_eq!(normal_header.compression, CompressionMethod::Deflated);
        assert_eq!(normal_header.uncompressed_size, 35);

        let secret_header = cd_headers
            .iter()
            .find(|h| String::from_utf8_lossy(&h.filename) == "secret.txt")
            .expect("未找到加密文件");
        assert!(secret_header.flags & ZIP_CRYPTO_FLAG != 0);

        let compressed_header = cd_headers
            .iter()
            .find(|h| String::from_utf8_lossy(&h.filename) == "compressed.txt")
            .expect("未找到压缩文件");
        assert_eq!(compressed_header.compression, CompressionMethod::Deflated);
        assert!(compressed_header.compressed_size < compressed_header.uncompressed_size);

        let dir_header = cd_headers
            .iter()
            .find(|h| String::from_utf8_lossy(&h.filename) == "test_dir/")
            .expect("未找到目录");
        assert_eq!(dir_header.compression, CompressionMethod::Stored);
        assert_eq!(dir_header.uncompressed_size, 0);

        // 3. 测试错误情况
        // 测试文件太小
        let invalid_file = NamedTempFile::new()?;
        invalid_file.as_file().write_all(b"too small")?;
        let mut invalid = File::open(invalid_file.path())?;
        assert!(ZipArchive::read_archive_info(&mut invalid).is_err());

        // 测试无效的中央目录
        let invalid_zip = NamedTempFile::new()?;
        let mut file = File::create(invalid_zip.path())?;
        file.write_all(&[0x50, 0x4B, 0x05, 0x06])?; // 结束记录签名
        file.write_all(&[0; 18])?; // 无效的结束记录数据
        let mut invalid = File::open(invalid_zip.path())?;
        let archive_info = ZipArchive::read_archive_info(&mut invalid)?;
        assert!(ZipArchive::read_central_directory_headers(&mut invalid, &archive_info).is_err());

        Ok(())
    }

    #[test]
    fn test_read_central_directory_edge_cases() -> anyhow::Result<()> {
        // 测试边界情况
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        let mut writer = ZipWriter::new(path)?;

        // 1. 空文件名
        writer.start_file("", FileOptions::new())?;
        writer.finish_file()?;

        // 2. 长文件名
        let long_name = "a".repeat(1000);
        writer.start_file(&long_name, FileOptions::new())?;
        writer.write_all(b"Long filename test")?;
        writer.finish_file()?;

        // 3. 特殊字符文件名
        writer.start_file("特殊字符.txt", FileOptions::new())?;
        writer.write_all("中文内容".as_bytes())?;
        writer.finish_file()?;

        writer.finish()?;

        // 读取并验证
        let mut file = File::open(path)?;
        let archive_info = ZipArchive::read_archive_info(&mut file)?;

        let cd_headers = ZipArchive::read_central_directory_headers(&mut file, &archive_info)?;

        assert_eq!(cd_headers.len(), 3);

        // 验证空文件名
        assert!(cd_headers.iter().any(|h| h.filename.is_empty()));

        // 验证长文件名
        let long_header = cd_headers
            .iter()
            .find(|h| h.filename.len() == 1000)
            .expect("未找到长文件名条目");
        assert_eq!(String::from_utf8_lossy(&long_header.filename), long_name);

        // 验证特殊字符
        let special_header = cd_headers
            .iter()
            .find(|h| String::from_utf8_lossy(&h.filename) == "特殊字符.txt")
            .expect("未找到特殊字符文件名条目");
        assert!(special_header.uncompressed_size > 0);

        Ok(())
    }

    #[test]
    fn test_read_central_directory_large_file() -> anyhow::Result<()> {
        let temp_file = NamedTempFile::new()?;
        let path = temp_file.path().to_str().unwrap();

        let mut writer = ZipWriter::new(path)?;

        // 创建大文件
        let large_data = vec![0u8; 1024 * 1024]; // 1MB
        writer.start_file("large.bin", FileOptions::new())?;
        writer.write_all(&large_data)?;
        writer.finish_file()?;

        writer.finish()?;

        // 读取并验证
        let mut file = File::open(path)?;
        let archive_info = ZipArchive::read_archive_info(&mut file)?;
        let cd_headers = ZipArchive::read_central_directory_headers(&mut file, &archive_info)?;

        assert_eq!(cd_headers.len(), 1);
        let header = &cd_headers[0];
        assert_eq!(header.uncompressed_size, 1024 * 1024);
        assert!(header.compressed_size < header.uncompressed_size);

        Ok(())
    }

    #[test]
    fn test_zip64_large_file() -> anyhow::Result<()> {
        use std::fs;
        use tempfile::tempdir;

        let temp_dir = tempdir()?;
        let large_file_path = temp_dir.path().join("large_file.bin");
        let zip_path = temp_dir.path().join("test_zip64.zip");

        // 创建一个大于4GB的测试文件（模拟，实际只创建小文件但设置ZIP64信息）
        let test_data = vec![0u8; 1024 * 1024]; // 1MB test data
        fs::write(&large_file_path, &test_data)?;

        // 测试ZIP64功能
        {
            let mut writer = ZipWriter::new(zip_path.to_str().unwrap())?;

            // 手动创建一个需要ZIP64的文件选项
            let mut options = FileOptions::new();
            options.with_compression(CompressionMethod::Stored);

            // 模拟大文件：设置大于4GB的大小
            let large_size = 5_000_000_000u64; // 5GB
            options.uncompress_size = large_size;
            options.compress_size = large_size as u32;
            options.crc32 = 0x12345678;
            options.skip_compression = true;

            writer.start_file("large_file.bin", options)?;

            // 由于这只是测试，我们写入少量数据但记录为大文件
            writer.write_all(&test_data[..1024])?; // 只写1KB，但记录为5GB

            let info = writer.finish_file()?;
            log::info!("Compression info: {:?}", info);

            writer.finish()?;
        }

        // 验证创建的ZIP64文件
        {
            let archive = ZipArchive::new(zip_path.to_str().unwrap())?;

            // 验证归档信息
            let info = archive.archive_info();
            log::info!("Archive ZIP64: {}", info.is_zip64);

            // 验证文件
            let files: Vec<_> = archive.files().collect();
            assert_eq!(files.len(), 1);

            let file = &files[0];
            assert_eq!(file.name(), "large_file.bin");

            // 验证是否识别为ZIP64
            log::info!("File needs ZIP64: {}", file.header.needs_zip64());
            log::info!("File origin size: {}", file.origin_size());
        }

        Ok(())
    }

    #[test]
    fn test_zip64_extended_info() -> anyhow::Result<()> {
        // 测试ZIP64扩展信息的序列化和反序列化
        let mut zip64_info = Zip64ExtendedInfo::new();
        zip64_info.uncompressed_size = Some(6_000_000_000u64); // 6GB
        zip64_info.compressed_size = Some(5_000_000_000u64); // 5GB
        zip64_info.local_header_offset = Some(1_000_000_000u64); // 1GB offset
        zip64_info.disk_start_number = Some(1);

        // 序列化
        let bytes = zip64_info.to_bytes_compat();
        assert_eq!(bytes.len(), 28); // 8+8+8+4 = 28 bytes

        // 反序列化
        let parsed_info = Zip64ExtendedInfo::from_bytes(&bytes)?;
        assert_eq!(parsed_info.uncompressed_size, Some(6_000_000_000u64));
        assert_eq!(parsed_info.compressed_size, Some(5_000_000_000u64));
        assert_eq!(parsed_info.local_header_offset, Some(1_000_000_000u64));
        assert_eq!(parsed_info.disk_start_number, Some(1));

        Ok(())
    }

    #[test]
    fn test_zip64_detection() {
        // 测试ZIP64需求检测函数

        // 小文件，不需要ZIP64
        assert!(!needs_zip64(1000, 800, 500, 10));

        // 大文件，需要ZIP64
        assert!(needs_zip64(5_000_000_000u64, 1000, 500, 10)); // 大原始大小
        assert!(needs_zip64(1000, 5_000_000_000u64, 500, 10)); // 大压缩大小
        assert!(needs_zip64(1000, 800, 5_000_000_000u64, 10)); // 大偏移量
        assert!(needs_zip64(1000, 800, 500, 70000)); // 大量文件

        // 测试归档级别的ZIP64检测
        assert!(!archive_needs_zip64(1000, 1000, 1000));
        assert!(archive_needs_zip64(70000, 1000, 1000)); // 大量文件
        assert!(archive_needs_zip64(1000, 5_000_000_000u64, 1000)); // 大中央目录
        assert!(archive_needs_zip64(1000, 1000, 5_000_000_000u64)); // 大偏移量
    }

    #[test]
    fn test_central_directory_header_zip64() -> anyhow::Result<()> {
        // 测试中央目录头的ZIP64功能
        let mut header = CentralDirectoryHeader::new();

        // 设置常规大小（不需要ZIP64）
        header.set_zip64_info(1000, 800, 500);
        assert!(!header.needs_zip64());
        assert_eq!(header.get_uncompressed_size(), 1000);
        assert_eq!(header.get_compressed_size(), 800);
        assert_eq!(header.get_local_header_offset(), 500);

        println!("Test phase 1 passed - small file");

        // 设置大文件大小（需要ZIP64）
        // 使用真正超过32位限制的值
        let large_uncompressed = 5_000_000_000u64; // 5GB > 4GB limit
        let large_compressed = 4_300_000_000u64; // > 4GB limit
        let large_offset = 3_000_000_000u64; // 3GB < 4GB limit

        header.set_zip64_info(large_uncompressed, large_compressed, large_offset);
        println!(
            "After set_zip64_info - needs_zip64: {}",
            header.needs_zip64()
        );

        if let Some(ref zip64_info) = header.zip64_extended_info {
            println!("ZIP64 extended info exists:");
            println!("  uncompressed_size: {:?}", zip64_info.uncompressed_size);
            println!("  compressed_size: {:?}", zip64_info.compressed_size);
            println!(
                "  local_header_offset: {:?}",
                zip64_info.local_header_offset
            );
        } else {
            println!("ZIP64 extended info is None!");
        }

        println!("Standard fields:");
        println!("  uncompressed_size: {}", header.uncompressed_size);
        println!("  compressed_size: {}", header.compressed_size);
        println!("  local_header_offset: {}", header.local_header_offset);

        assert!(header.needs_zip64());
        assert_eq!(header.get_uncompressed_size(), large_uncompressed);
        assert_eq!(header.get_compressed_size(), large_compressed);
        assert_eq!(header.get_local_header_offset(), large_offset);

        // 验证标准字段：
        // - uncompressed_size (5GB) 超过 MAX_ZIP_SIZE，应设置为 MAX_ZIP_SIZE
        // - compressed_size (4.3GB) 超过 MAX_ZIP_SIZE，应设置为 MAX_ZIP_SIZE
        // - local_header_offset (3GB) 小于 MAX_ZIP_SIZE，应保持原值
        assert_eq!(header.uncompressed_size, MAX_ZIP_SIZE);
        assert_eq!(header.compressed_size, MAX_ZIP_SIZE);
        assert_eq!(header.local_header_offset, large_offset as u32);

        // 验证ZIP64扩展信息存在
        assert!(header.zip64_extended_info.is_some());

        Ok(())
    }

    #[test]
    fn test_zip64_extra_field_parsing() -> anyhow::Result<()> {
        // 测试ZIP64额外字段的解析
        let mut header = CentralDirectoryHeader::new();

        // 手动构造ZIP64额外字段
        let mut extra_field = Vec::new();
        extra_field.extend_from_slice(&ZIP64_EXTRA_FIELD_ID.to_le_bytes()); // 字段ID
        extra_field.extend_from_slice(&24u16.to_le_bytes()); // 数据长度 (8+8+8)
        extra_field.extend_from_slice(&6_000_000_000u64.to_le_bytes()); // 未压缩大小
        extra_field.extend_from_slice(&5_000_000_000u64.to_le_bytes()); // 压缩大小
        extra_field.extend_from_slice(&1_000_000_000u64.to_le_bytes()); // 本地头偏移

        header.extra_field = extra_field;

        // 解析ZIP64字段
        header.parse_zip64_extra_field()?;

        // 验证解析结果
        assert!(header.zip64_extended_info.is_some());
        let zip64_info = header.zip64_extended_info.unwrap();
        assert_eq!(zip64_info.uncompressed_size, Some(6_000_000_000u64));
        assert_eq!(zip64_info.compressed_size, Some(5_000_000_000u64));
        assert_eq!(zip64_info.local_header_offset, Some(1_000_000_000u64));

        Ok(())
    }
}
